在我工作的代码库的尘土飞扬的角落里,我遇到了一个类似于以下的类层次结构:
class Base1
{
int base1;
};
class Base2
{
int base2;
};
template <typename T> class A : public Base1
{
T _specialT;
};
template <> class A<int> : public Base2
{
int _special;
};
在A的专业化中使用Base2令我感到惊讶。我一直在四处寻找它究竟意味着什么,未能找到任何这种设计的例子或讨论。
在我看来,这样做会导致A从Base1和Base2继承,而非专用的A的其他用途将仅从Base1继承。这让我有几个问题:
答案 0 :(得分:4)
Base1
,只有<int>
专门化继承自Base2
(仅来自Base2
)。不知道使用它的上下文,我无法回答2.或3.
您经常可以在模板元编程中看到从不同类型派生的特化。例如:
template<typename T, typename U>
struct is_same : std::false_type {};
template<typename T>
struct is_same<T,T> : std::true_type {};
这是完全有效的事情。这是否是一件好事完全取决于正在解决的问题。
答案 1 :(得分:2)
从正常情况来看,模板的特化是完全独立的,代码方面的。因此,A<int>
不会来自Base1
和Base2
,只能来自Base2
。
有些情况下,专业化是好的设计。当然,这是不可能从你抽象的例子中得知。
答案 2 :(得分:2)
请记住,类模板的不同实例化是不同的独立类。模板的专业化不会在一般情况下添加内容,而是完全替换它。
因此,A<int>
是一个派生自Base2
的类,有一个名为_special
的int成员,A<double>
和A<char>
是两个独立的不同类两者都碰巧派生自Base1
,每个都有一个类型为double和char的成员,分别名为_specialT
。
所以:
Base1
上使用A<int>
的某些方法(或使用_specialT
成员),那么会出现编译错误,这会让人感到惊讶他没有看到专业化。一个非常流行的例子是std::vector<bool>
在标准中的特殊化,与“普通”std::vector
的行为不同,被广泛认为是破碎的。这种模式(源自不同基础的特化)通常用于模板元编程。一个(非常)简单的例子:
template <class T>
struct is_int_or_double : std::false_type
{};
template <>
struct is_int_or_double<int> : std::true_type //another base class!
{};
template <>
struct is_int_or_double<double> : std::true_type //another base class!
{};