C++ 类模板专门化从不同的基类继承是否合法?

C++ 类模板专门化从不同的基类继承是否合法?,c++,templates,inheritance,specialization,C++,Templates,Inheritance,Specialization,我遇到过这样一种情况:我的类模板部分专业化共享了大量代码,将其转移到基类中是有意义的。然而,并不是所有的专业都有相同的基础课程 以下示例代码在GCC 7.1中编译无误: struct foo_base_1 { void bar() { std::cout << "base 1" << std::endl; }; }; struct foo_base_2 { void bar() { std::cout << "base 2" << std::en

我遇到过这样一种情况:我的类模板部分专业化共享了大量代码,将其转移到基类中是有意义的。然而,并不是所有的专业都有相同的基础课程

以下示例代码在GCC 7.1中编译无误:

struct foo_base_1 { void bar() { std::cout << "base 1" << std::endl; }; };

struct foo_base_2 { void bar() { std::cout << "base 2" << std::endl; }; };

template <typename A, typename B>
struct foo { };

template <typename A>
struct foo<A, int> : foo_base_1 { };

template <typename A>
struct foo<A, double> : foo_base_2 { };

int main()
{
    foo<int, int> x;
    foo<int, double> y;

    x.bar();
    y.bar();
}

<代码>结构> FooBaseBase1{VultBar(){STD::CUT

每个模板实例化是它自己的一个单独类。正如任何普通类可以从您所希望的任何基类继承一样,模板实例化也可以这样做。请考虑下面的例子:

template <typename Base>
class Derived : public Base
{
};
模板
派生类:公共基
{
};
绝对合法

举例来说,这是该系统的基础

如果您现在决定以不同于原始/主模板模式的方式实现特定的实例化(因此您需要专门化;或者一组,然后部分地实现),这并不重要

该标准似乎对该主题有点简短:

17.5.1类别模板[临时类别]
1类模板定义了一组无限相关类型的布局和操作。
2[示例:单个类模板列表可能提供一组无界的类定义:每个类型T都有一个类列表,每个类列表描述T类型元素的链接列表。类似地,描述连续动态数组的类模板数组可能定义如下:[一些示例模板声明] 前缀模板指定正在声明模板,并且可以在声明中使用类型名T。换句话说,数组是一个参数化类型,其参数为T。 -[结束示例]

[由我突出显示],但稍后在定义类型特征时使用相同的模式:

23.15.3助手类[meta.help]
[积分常数的定义]
1类模板integral_常量、别名模板bool_常量及其关联的typedef名称true_type和false_type用作基类,以定义各种类型特征的接口

随后,本标准使用了“具有基本特征”的措辞,如:

23.15.4一元类型特征[元一元]
1本子条款包含可用于在编译时查询类型属性的模板。
2如果相应条件为真,则这些模板中的每一个模板应为一个单一类型特征(23.15.1),其基本特征为真类型,否则为假类型

结合前面的引文,我们可以得出结论,根据条件是否满足,有选择地继承
true\u类型
false\u类型
至少是合法的。很难说这种措辞是否强制执行这种继承,或者定义模板使其只有像
true\u-type
false\u-type
那样的行为,而不显式继承自(但这是另一回事…)


当然不是权威性的,我个人倾向于前一种解释,因为前面的“被用作”(与“可以用作”相反)这个模式在标准库中都是用于类型特征的。通常基本模板将从<代码> STD::FalsEyType 派生,并且有一些派生自<代码> STD::TrtrueType < /C>的专门化。请考虑<代码> FoO >简单地>代码> Foo{}。没有任何基类:)@MilesBudnek我没有考虑过这一点,但这是一个很好的实际例子。我很高兴这是基于所有人的解释的合法性。但是我不愿意接受这样的答案。你能详细说明一下“绝对合法”吗既然这个答案基本上是要求人们相信你的话?也许是关于标准库如何在类型特征方面使用
std::true_type
?谢谢你扩展它,希望它能帮助未来的谷歌。实际上,
class-Derived:public-Base{};
将是CRTP。@Deduplicator我刚才说过“它是”的基础,而不是“它是”。CRTP在提供的链接中进行了解释……目的是提供一个用例。