gcc接受以下代码,clang拒绝。
struct S
{
struct Type
{
};
operator Type()
{
return Type();
}
};
void f(S& s)
{
s.operator Type(); // error: unknown type name 'Type'
}
该标准称CCD_;在对象表达式"的类中查找;CCD_ 2。看起来gcc在搜索中包括了S
的成员,而clang只考虑没有。哪个是正确的?S
,而它的基类
C++工作草案N3337:的相关报价
3.4.5类成员访问[basic.lookup.classref]/7
如果id表达式是一个转换函数id,那么它的转换类型id是在对象表达式和名称(如果找到)。否则,它将在整个后缀表达式。
在这种特殊情况下,gcc是正确的。查找规则规定,Type
的查找应首先在对象类型的上下文中执行,然后在使用表达式的上下文中进行。该标准甚至提供了一个例子,虽然不完全与您的相似:
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
}
查找从::N::A
内部开始,在那里查找注入的名称A
并将其解析为::N::A
。