无意中发现g++(5.2.0)编译如下
template<typename T>
struct A {
int x;
struct B {
void foo() {
x = 1;
}
};
};
甚至统计 A
和 A::B
, 提供成员(member) B::foo
未使用。您合理地得到了 x
的编译错误作为 A
的非静态成员即使只是编译空操作语句 &A<int>::B::foo;
.
clang (3.6.2) 然而拒绝模板,即使 A
根本没有实例化,因为它说非静态成员名称 x
不能在 B
内使用而只是阅读模板定义。
这是 g++ 中的错误还是 clang 对未实例化的模板成员过于严格?
最佳答案
x
在您的代码中是一个非依赖名称,并且标准呈现一个无法有效实例化的模板,无论您作为模板参数提供的格式是否正确,都不需要诊断(实际上这也适用于“temploids”,例如标准显示。也就是说,规则同样适用于类模板的成员)。
您的代码与访问周围类名称的任何普通类一样无效。请注意,方向在这里很重要。以下内容不会格式错误(因为您可以特化A<T>::B
,例如,x
对于A<int>::B
是一个静态成员。
template<typename T>
struct A {
struct B {
int x;
};
void f() {
B::x = 1;
}
};
但是,封闭类模板的类型称为当前实例化,这意味着它的含义始终保持不变,不能根据模板参数而改变。因此,模板定义本身可能会因某些用途(例如您的用途)而呈现格式错误。
关于c++ - 如果嵌套类型(未访问)带有无法编译的方法,是否可以实例化模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32920488/