我定义了一个这样的模板类:
template <typename A, typename B>
class SomeThing
{
~~~
};
我希望使用SomeThing<X, Y>
。然后那不是很好,所以我这样做了:
typedef SomeThing<X, Y> SomeNewThing;
但是,我还有一些问题。 SomeNewThing的转发声明将是这种形式。
class X;
class Y;
template <typename A, typename B> class SomeThing;
typedef SomeThing<X, Y> SomeAppropriateNewName;
在包含此类的每个标头中写入此内容很不方便。 因此,我尝试使用继承而不是使用typedef。
class SomeAppropriateNewName : public Something<X, Y> {};
除了继承之外,它只是一个空类。前瞻声明将是这样的。
class SomeAppropriateNewName;
似乎一切都应该正常工作。
SomeNewThing
的行为与SomeThing<X, Y>
完全相同吗?
这个类的行为与其父类相同吗? 没有任何区别吗?
答案 0 :(得分:1)
SomeAppropriateNewName
有一些差异。其中一些你可以解决。
SomeAppropriateNewName
应该将构造函数和其他特殊成员函数转发给它的父元素。
如果将SomeAppropriateNewName *
删除为Something<X, Y> *
,则在没有virtual
析构函数的情况下调用未定义的行为。实际上,如果SomeAppropriateNewName
为空,一切都可能没问题。
SomeAppropriateNewName
不会像Something<X, Y>
那样模式匹配模板重载。这是一种独特的类型。它可以很好地与函数参数匹配(有一些细微差别),但如果你把它传递给:
template<class T> struct is_something:std::false_type{};
template<class X, class Y> struct is_something<Something<X,Y>>:std::true_type{};
然后Something<X, Y>
给出true,而SomeAppropriateNewName
给出false。
对void*
的往返必须采用完全相同的类型,除非我认为这两种类型都是标准布局。