代码之家  ›  专栏  ›  技术社区  ›  Fibbs Kerrek SB

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

  •  4
  • Fibbs Kerrek SB  · 技术社区  · 8 年前

    我遇到过这样一种情况:我的类模板部分专业化共享了大量代码,将其移到基类中是有意义的。然而,对于所有的专业来说,拥有 相同的 基类。

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

    我意识到,尽管是同一类的专业,但它们实际上是不同类型的。尽管如此 感觉 同一个类可以从不同的基继承是错误的。

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

    1 回复  |  直到 8 年前
        1
  •  5
  •   Aconcagua    8 年前

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

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

    绝对合法。。。

    例如,这是 curiously recurring template pattern .

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

    标准似乎有点简短:

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

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

    23.15.3帮助类[meta.help]
    [积分常数的定义]
    1类模板integral_constant、别名模板bool_constant及其关联的typedef名称true_type和false_type用作基类来定义各种类型特征的接口。

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

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

    再加上之前的引文,我们可以得出结论,从任何一方继承遗产至少是合法的 true_type false_type 有选择地,根据是否满足条件。很难说这一措辞是否强制执行了这种继承,或者定义模板是否合法,以便它们只 表现 喜欢 真实类型 错误类型 没有明确继承(这是另一回事,尽管…)。

    当然,不权威,我个人倾向于前一种解释,因为前面的“都是用作的”(与“可以用作的”相反)。