2016-05-18 19 views
15

Si consideri il seguente codice:Cast operatore, GCC e clang: quale compilatore ha ragione?

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

Compila con GCC (4.9/5.1/6.1), ma non riesce a compilare con clangore (3.8/3.7).
L'errore restituito è:

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

quale compilatore è proprio in questo caso e perché?

Nota

Risolvere si tratta di una questione di qualificazione T:

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

La questione non è su come farlo funzionare.

risposta

15

Credo che questo sia clang bug (presentata come #27807)

Da [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 viene prima alzò lo sguardo nella classe di S, che dovrebbe trovare il typedef e, quindi, termina chiamando operator int().

+0

Vedi http://wg21.link/cwg1111, rettificato leggermente http://wg21.link/cwg1220 –

+0

@Barry Grazie, ero ad aprire un bug per clang ieri, ma non sono stato in grado di trova/capisce la sezione giusta del riferimento. Ancora per imparare _how_ a leggerlo correttamente ... :-( – skypjack

+0

@ T.C. Quindi, stai dicendo che in realtà è un _bug del linguaggio_? :-) – skypjack

Problemi correlati