Des*_*tor 10 c++ g++ visual-c++ language-lawyer clang++
考虑以下计划:
struct S {
using T = float;
operator T() { return 9.9f; }
};
int main() {
S m;
S::T t = m;
t = m.operator T(); // Is this correct ?
}
Run Code Online (Sandbox Code Playgroud)
该程序在g ++中编译良好(请参阅此处的实时演示)
但它在clang ++,MSVC++和Intel C++编译器的编译中失败了
clang ++给出以下错误(请参阅此处的在线演示)
main.cpp:8:20: error: unknown type name 'T'; did you mean 'S::T'?
t = m.operator T(); // Is this correct ?
^
S::T
main.cpp:2:11: note: 'S::T' declared here
using T = float;
Run Code Online (Sandbox Code Playgroud)
MSVC++给出以下错误(请参阅此处的实时演示)
source_file.cpp(8): error C2833: 'operator T' is not a recognized operator or type
source_file.cpp(8): error C2059: syntax error: 'newline'
Run Code Online (Sandbox Code Playgroud)
英特尔C++编译器也拒绝此代码(请参阅此处的实时演示)
那么,问题是哪个编译器就在这里?这里g ++是不正确的还是其他3个编译器不正确?C++标准对此有何看法?
如果id-expression是conversion-function-id,则首先在对象表达式的类中查找其conversion-type-id,并使用名称(如果找到).否则,它将在整个postfix-expression的上下文中查找 .在每个查找中,仅考虑表示其特化类型的类型或模板的名称.[ 例如:
Run Code Online (Sandbox Code Playgroud)struct A { }; namespace N { struct A { void g() { } template <class T> operator T(); }; } int main() { N::A a; a.operator A(); // calls N::A::operator N::A }- 结束例子 ]
这表明该示例可能没问题,尽管在上面的示例中,A先前已声明为类型名称,可见main.
这在1999年提交的核心问题156中进行了讨论:
怎么样:
Run Code Online (Sandbox Code Playgroud)struct A { typedef int T; operator T(); }; struct B : A { operator T(); } b; void foo() { b.A::operator T(); // 2) error T is not found in the context // of the postfix-expression? }这种解释是否正确?或者只有
T在两个范围中找到并引用不同的实体时才意味着这是一个错误?Erwin Unruh:意图是你在两种情况下都看.如果你只发现一次,那就是符号.如果你在两者中找到它,那么两个符号在某些方面必须是"相同的".(如果你没找到它,那就是错误).
所以我说Clang是错的:在某种程度上,在措辞中表达的意图是我们发现T,即使只是在课堂上.
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |