在同一个类中是否有使用成员类模板特化的符合标准的方法?
struct S {
template<typename T> struct Data;
// Explicit (AKA full) template specialization is not allowed here.
template<> struct Data<char> {};
template<> struct Data<int> {};
Data<char> d1;
Data<int> d2;
};
不起作用,因为类内部不允许成员类模板的完全专业化。在这种情况下,一些编译器选择忽略神圣标准并且对代码感到满意,但有些编译器遵循规则。
struct S {
template<typename T> struct Data;
// Specializations are not defined at this point.
Data<char> d1;
Data<int> d2;
};
template<> struct S::Data<char> {};
template<> struct S::Data<int> {};
也不起作用,因为在定义之前无法使用专业化。
我知道我可以将成员类模板移出类,但这不是重点。
愚蠢的是,如果我仅仅因为这个原因使用额外的模板参数,我可以解决禁止类内模板专业化的问题:
struct S {
template<typename T, typename NotUsed = void> struct Data;
// Now it's a partial template specialization, which is allowed.
template<typename NotUsed> struct Data<char, NotUsed> {};
template<typename NotUsed> struct Data<int, NotUsed> {};
Data<char> d1;
Data<int> d2;
};
现在可以了,因为类内部允许部分模板特化。
我是否缺少某种“正确方式”的方法——在课堂外进行专业化,但仍然能够在课堂内使用它?我假设标准的 C++17 版本。
答案 0 :(得分:2)
在同一个类中是否有使用成员类模板特化的符合标准的方法?
是:使用符合 C++17 的编译器。
C++17 directly states:
<块引用>可以在可以定义相应主模板的任何范围内声明显式特化
然而,C++14 says:
<块引用>应在包含专用模板的命名空间中声明显式专业化。
您的编译器似乎遵循 C++14 规则。如果将它显式设置为 C++17(或更高版本)不能修复它,那么这是一个编译器错误。