class 模板特化从不同的基础 class 继承是否合法?

Is it legal for class template specialisations to inherit from different base classes?

我遇到过这样一种情况,我的 class 模板部分特化共享大量代码,将其移至基础 class 是有意义的。但是,所有专业都具有 相同的 基础 class.

是没有意义的

以下示例代码在 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();
}

我意识到尽管是相同 class 的专业化,但它们实际上是不同的类型。不过,感觉 错误的是,相同的 class 可以从不同的基础继承。

我想要的是一些保证,这没关系。我找不到标准的相关部分,我不愿意仅仅因为它编译就相信它(我之前被咬过)。

每个模板实例都是一个单独的 class。正如任何普通的 class 都可以从您想要的任何基础 class 继承,模板实例化也可以这样做。考虑以下示例:

template <typename Base>
class Derived : public Base
{
};

绝对合法...

例如,这是 curiously recurring template pattern 的基础。

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

题目好像标准有点短:

17.5.1 Class templates [temp.class]
1 A class template defines the layout and operations for an unbounded set of related types.
2 [Example: A single class template List might provide an unbounded set of class definitions: one class List for every type T, each describing a linked list of elements of type T. Similarly, a class template Array describing a contiguous, dynamic array might be defined like this: [ some sample template declaration ] The prefix template specifies that a template is being declared and that a type-name T may be used in the declaration. In other words, Array is a parameterized type with T as its parameter. — end example]

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

23.15.3 Helper classes [meta.help]
[definition of integral_constant]
1 The class template integral_constant, alias template bool_constant, and its associated typedef-names true_type and false_type are used as base classes to define the interface for various type traits.

随后,标准使用 "having a base characteristic of" 的措辞,如:

23.15.4 Unary type traits [meta.unary]
1 This subclause contains templates that may be used to query the properties of a type at compile time.
2 Each of these templates shall be a UnaryTypeTrait (23.15.1) with a base characteristic of true_type if the corresponding condition is true, otherwise false_type.

结合前面的引用,我们可以得出结论,根据是否满足条件,有选择地从 true_typefalse_type 继承至少是合法的。很难说这种措辞是否强制执行这种继承,或者定义模板是否合法,使得它们仅 表现 true_typefalse_type 没有明确继承自(不过,这是另一回事...)。

不权威,当然,由于前面的"are used as"(对比"can be used as"),我个人倾向于前一种解释。