Operator cast, GCC and clang: which compiler is ri

2020-04-02 06:07发布

Consider the following code:

struct S {
    using T = int;
    operator T() { return 42; }
};

int main() {
    S s;
    S::T t = s;
    // Is the following line correct?
    t = s.operator T();
}

It compiles with GCC (4.9/5.1/6.1), but it fails to compile with clang (3.8/3.7).
The error returned is:

error: unknown type name 'T'; did you mean 'S::T'?

Which compiler is right in this case and why?

Note

Solving it is a matter of qualifying T:

t = s.operator S::T();

The question is not about how to make it work.

1条回答
够拽才男人
2楼-- · 2020-04-02 07:00

I believe this is clang bug (submitted as #27807)

From [basic.lookup.classref]:

If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression. In each of these lookups, only names that denote types or templates whose specializations are types are considered. [ Example:

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
}

—end example ]

In t = s.operator T();, T is first looked up in the class of S, which should find your typedef and hence end up calling operator int().

查看更多
登录 后发表回答