请参阅下列代码:
template <class T>
struct X {
enum class E { e0 };
template <class U, E e>
struct Y {};
template <class U>
struct Y<U, E::e0> {
static int f() { return 0; }
};
};
int main() {
X<int>::Y<int, X<int>::E::e0>::f();
}
VC++ 15.7.5生成一条错误消息:
1> test.cpp
1> some_directory\test.cpp(15): error C2039: 'f': is not a member of 'X<int>::Y<int,X<int>::E::e0>'
1> some_directory\test.cpp(15): note: see declaration of 'X<int>::Y<int,X<int>::E::e0>'
1> some_directory\test.cpp(15): error C3861: 'f': identifier not found
然而,GCC和Clang似乎接受了这个代码。
哪一个是对的?
编辑
在旧版本的VC++上生成以下错误消息:
source_file.cpp(9): error C2754: 'X<T>::Y<U,>': a partial specialization cannot have a dependent non-type template parameter
source_file.cpp(12): note: see reference to class template instantiation 'X<T>' being compiled
source_file.cpp(16): error C2039: 'f': is not a member of 'X<int>::Y<int,X<int>::E::e0>'
source_file.cpp(16): error C3861: 'f': identifier not found
所以我认为VC++拒绝编译的原因是enum class E
是在模板类中定义的。实际上,如果我将enum class E
移到X
之外,错误就会消失(无论是在旧版本还是最近的15.7.5中)。
这种情况真的是对依赖的非类型模板参数进行部分专门化吗?
发布于 2018-07-15 02:05:25
GCC和Clang接受它是正确的。这都是根据[temp.class.spec]/5,它也有一个支持的例子:
类模板部分专门化可以在定义相应主模板的任何作用域中声明(namespace.memdef、class.mem、temp.mem)。 示例: 模板结构A{ struct {模板结构B{ };模板结构B { };//部分专门化#1 };};//部分专门化A::C::B模板模板结构A::C::B { };// #2 A::C::B absip;//使用部分专门化#2 - 端例
MSVC的解决方法可能是在命名空间范围内尝试并专门化成员模板。
至于你的编辑,我会说MSVC仍然是错误的。相关标准在[temp.class.spec]/8
在类模板部分专门化的参数列表中,适用以下限制:
将其应用于struct Y<U, E::e0>
中的示例:枚举的类型是否依赖于Y
的另一个模板参数?答案是否定的。它当然依赖于X<T>
,但这是的另一个模板专门化。在编写定义时,我们的模板不一定是专门化的。
https://stackoverflow.com/questions/51347272
复制相似问题