Операторский бросок, GCC и clang: какой компилятор прав?

Рассмотрим следующий код:

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();
}

Он компилируется с помощью GCC (4.9/5.1/6.1), но он не компилируется с помощью clang (3.8/3.7).
Возвращаемая ошибка:

error: неизвестное имя типа 'T'; вы имели в виду "S:: T"?

Какой компилятор прав в этом случае и почему?

Примечание

Решение этого вопроса зависит от квалификации T:

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

Вопрос не в том, как заставить его работать.

Ответ 1

Я считаю, что это ошибка clang (представленная как # 27807)

Из [basic.lookup.classref]:

Если 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
}

-end пример]

В t = s.operator T();, T сначала просматривается в классе S, который должен найти ваш typedef и, следовательно, вызывает вызов operator int().