考虑以下计划:
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 ?
}
该程序在g ++中编译得很好(参见实时演示here)
但它在clang ++,MSVC ++&英特尔C ++编译器
clang ++给出了以下错误(请参阅实时演示here)
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;
MSVC ++提供以下错误(请参阅实时演示here)
source_file.cpp(8): error C2833: 'operator T' is not a recognized operator or type
source_file.cpp(8): error C2059: syntax error: 'newline'
英特尔C ++编译器也拒绝此代码(请参阅实时演示here)
所以,问题是哪个编译器就在这里?这里g ++是不正确的还是其他3个编译器不正确? C ++标准对此有何看法?
答案 0 :(得分:8)
如果 id-expression 是 conversion-function-id ,首先会查找 conversion-type-id 在对象表达式的类中,如果找到,则使用。否则,它会在整个上下文中查找 后缀表达式。在每个查找中,仅考虑表示其特化类型的类型或模板的名称。 [示例:
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年提交的core issue 156中进行了讨论:
怎么样:
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
,即使只是在课堂上。