问题描述:

I define a template class like this:

template <typename A, typename B>

class SomeThing

{

~~~

};

and I want to use SomeThing<X, Y>. Then that isn't neat, so I did this:

typedef SomeThing<X, Y> SomeNewThing;

However, I have some problem yet. The forwarding declaration of SomeNewThing will be this form.

class X;

class Y;

template <typename A, typename B> class SomeThing;

typedef SomeThing<X, Y> SomeAppropriateNewName;

It is inconvenient to write this in every header that contains this class.

So, rather than using of typedef, I try using inheritance.

class SomeAppropriateNewName : public Something<X, Y> {};

Except inheritance, it is just an empty class. The forward declaration will be like this.

class SomeAppropriateNewName;

It seems like everything should work correctly.

Does SomeNewThing act in exactly same way that SomeThing<X, Y> do?

Does this class act in the same way of its parent?

Isn't there any difference?

网友答案:

SomeAppropriateNewName has a few differences. Some of which you can fix.

SomeAppropriateNewName should forward constructors and other special member functions to its parent.

If you delete a SomeAppropriateNewName * as a Something<X, Y> * you invoke undefined behavior without a virtual destructor. In practice, if SomeAppropriateNewName is empty everything may be fine.

SomeAppropriateNewName does not pattern-match template overloads like Something<X, Y> does. It is a distinct type. It will work pretty well with function argument matching (there are slight differences), but if you pass it to:

template<class T> struct is_something:std::false_type{};
template<class X, class Y> struct is_something<Something<X,Y>>:std::true_type{};

then Something<X, Y> gives true, while SomeAppropriateNewName gives false.

Round-tripping to void* has to go to the exact same type, unless both types are standard layout I think.

相关阅读:
Top