Tl; dr:解决该问题的最便携和最不广泛的方法似乎是::Derived
在您的示例中使用限定名称:
templatestruct Derived : Base { Derived(const T& _t) : Base (_t) { } };
问题是编译器不符合C++ 11.
与普通(非模板)类一样,类模板具有注入类名(第9节).注入的类名可以用作模板名或类型名.当它与template-argument-list一起使用时,作为模板模板参数的模板参数,或作为友元类模板声明的详细说明类型说明符中的最终标识符,它引用类模板本身.
因此,您的代码应该编译,但遗憾的是,我测试的所有编译器(clang 3.7,Visual Studio 2015和g ++ 5.3)都拒绝这样做.
Afaik,你应该能够在Derived
定义中以各种方式表示模板:
直接使用注入的名称 Derived
类模板的限定名称 ::Derived
使用注入的类名称,将其指定为模板名称 Derived
使用限定名称,再次将其指定为模板名称 ::template Derived
这些编译器关于这四个选项的编译状态如下(使用anonymus命名空间;其中+
=成功编译):
+------------------------------+----------+---------+-----------+ | Method | MSVS2015 | g++ 5.3 | clang 3.7 | +------------------------------+----------+---------+-----------+ | Derived | - | - | - | | ::Derived | + | + | + | | Derived::template Derived | - | - | + | | ::template Derived | + | - | + | +------------------------------+----------+---------+-----------+
给名称空间命名时X
,图片会稍微改变(即g++
现在接受X::template Derived
而拒绝::template Derived
):
+---------------------------------+----------+---------+-----------+ | Method | MSVS2015 | g++ 5.3 | clang 3.7 | +---------------------------------+----------+---------+-----------+ | Derived | - | - | - | | X::Derived | + | + | + | | X::Derived::template Derived | - | - | + | | X::template Derived | + | + | + | +---------------------------------+----------+---------+-----------+
在类模板中,inject-class-name(Derived
在您的示例中)可以是类型名称和模板名称.该标准指定在用作模板模板参数的参数时应该考虑将模板命名(因此您的代码应该起作用),但遗憾的是一些编译器尚未实现此功能.
一种解决方法是使用限定名称,这样您就不会使用inject-class-name,而是直接命名模板:
templatestruct Derived : Base { Derived(const T& _t) : Base (_t) { } };