名称查找“在对象表达式的类中”应该找到该类的成员吗?

时间:2013-08-14 21:25:38

标签: c++ language-lawyer

gcc接受以下代码,而clang拒绝它。

struct S
{
    struct Type
    {
    };
    operator Type()
    {
        return Type();
    }
};
void f(S& s)
{
    s.operator Type(); // error: unknown type name 'Type'
}

标准说Type“在对象表达式”S的类中查找。似乎gcc在搜索中包含S的成员,而clang 仅考虑S,而其基类则不会。哪个是对的?

C ++工作草案N3337的相关引用:

  

3.4.5类成员访问[basic.lookup.classref] / 7

     

如果id-expression是一个转换函数id,它的conversion-type-id首先在的类中查找   对象表达式,使用名称(如果找到)。否则,它会在整个上下文中查找   后缀表达式。

1 个答案:

答案 0 :(得分:1)

在这个特殊情况下,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并将其解析为{{1}}。