如果嵌套类型(未访问)带有无法编译的方法,是否可以实例化模板?
Can a template be instantiated if there is nested type (not accessed) with a method that cannot be compiled?
无意中发现g++(5.2.0)编译如下
template<typename T>
struct A {
int x;
struct B {
void foo() {
x = 1;
}
};
};
甚至实例化 A
和 A::B
,前提是不使用成员 B::foo
。即使只编译无操作语句 &A<int>::B::foo;
.
,你也会合理地得到一个编译错误,因为 x
是 A
的非静态成员
clang (3.6.2) 但是拒绝模板,即使 A
根本没有实例化,因为它说非静态成员名称 x
不能在内部使用 B
而只是阅读模板定义。
这是 g++ 中的错误还是 clang 对未实例化的模板成员过于严格?
[temp.res]/8 说:
No diagnostic
shall be issued for a template for which a valid specialization can be generated. If no valid specialization can
be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic
required.
我相信第二句适用于 B
中未使用的部分。如果函数没有被实例化,编译器永远不需要意识到它不能被实例化。
代码中的 x
是一个非依赖名称,标准呈现的模板无法有效实例化,无论您作为模板参数提供的格式是否正确,都不需要诊断(实际上这也适用于 "temploids",如标准中的示例所示。也就是说,规则同样适用于 class 模板的成员)。
您的代码与访问周围 class 名称的任何正常 class 一样无效。请注意,方向在这里很重要。以下 不会 格式错误(因为您 可以 专门化 A<T>::B
这样 x
对于 A<int>::B
是一个静态成员,例如。
template<typename T>
struct A {
struct B {
int x;
};
void f() {
B::x = 1;
}
};
然而,封闭 class模板的类型称为当前实例化,这意味着它的含义始终保持相同,不能根据模板参数更改。因此,模板定义本身可能会因某些用途(例如您的用途)而呈现格式错误。
无意中发现g++(5.2.0)编译如下
template<typename T>
struct A {
int x;
struct B {
void foo() {
x = 1;
}
};
};
甚至实例化 A
和 A::B
,前提是不使用成员 B::foo
。即使只编译无操作语句 &A<int>::B::foo;
.
x
是 A
的非静态成员
clang (3.6.2) 但是拒绝模板,即使 A
根本没有实例化,因为它说非静态成员名称 x
不能在内部使用 B
而只是阅读模板定义。
这是 g++ 中的错误还是 clang 对未实例化的模板成员过于严格?
[temp.res]/8 说:
No diagnostic shall be issued for a template for which a valid specialization can be generated. If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.
我相信第二句适用于 B
中未使用的部分。如果函数没有被实例化,编译器永远不需要意识到它不能被实例化。
代码中的 x
是一个非依赖名称,标准呈现的模板无法有效实例化,无论您作为模板参数提供的格式是否正确,都不需要诊断(实际上这也适用于 "temploids",如标准中的示例所示。也就是说,规则同样适用于 class 模板的成员)。
您的代码与访问周围 class 名称的任何正常 class 一样无效。请注意,方向在这里很重要。以下 不会 格式错误(因为您 可以 专门化 A<T>::B
这样 x
对于 A<int>::B
是一个静态成员,例如。
template<typename T>
struct A {
struct B {
int x;
};
void f() {
B::x = 1;
}
};
然而,封闭 class模板的类型称为当前实例化,这意味着它的含义始终保持相同,不能根据模板参数更改。因此,模板定义本身可能会因某些用途(例如您的用途)而呈现格式错误。