2016-07-27 11 views
12

Rozważmy przykład:Czy "używanie Base :: operator T" jest dozwolone, gdzie `T` jest parametrem typu szablonu?

struct B { operator int(); }; 

template<class T> 
struct X:B 
{ 
    using B::operator T; 
}; 

GCC przyjmuje kod, a Clang i MSVC odrzuca. Co jest poprawne?

Zauważ, że jeśli typ bazowy jest zależny, wszystkie kompilatory zaakceptować kod:

template<class T> 
struct B { operator T(); }; 

template<class T> 
struct X:B<T> 
{ 
    using B<T>::operator T; 
}; 
+1

Jeśli użyjesz 'operatora int()' w 'B' funkcji szablonowej konwersji (np.' Template operator T(); ') działa, a jeśli wyspecyfikujesz to dla' int', to również działa i wywołuje specjalizacja, o ile rozumiem, standard go zabrania (* "Ponieważ specjalizacje szablonów członków dla funkcji konwersji nie są odnajdywane przez wyszukiwanie nazw, nie są uwzględniane, gdy deklaracja użycia określa funkcję konwersji (14.5.2) . "*). Również clang może znaleźć 'operator T' jeśli wywołasz go w funkcji składowej, więc myślę, że gcc ma rację. – Holt

Odpowiedz

3

myślę GCC ma rację, w § 7.3.3/1, możemy znaleźć:

Zbiór deklaracji wprowadzonych przez Użycie-deklaracja zostanie znaleziona poprzez wykonanie kwalifikowanego sprawdzania nazw (3.4.3, 10.2) dla nazwy w deklaracji użycia, z wyłączeniem funkcji ukrytych w sposób opisany poniżej.

Nie widzę żadnego powodu, dlaczego operator T nie będzie można znaleźć, rzeczywiście:

template<class T> 
struct X: B { 
    T f() { return B::operator T; } 
}; 

... kompiluje grzywny z g ++ i szczęk (nie testowałem na MSVC).

Nie mogę znaleźć coś w standardowej specyficzne dla konwersji functionsfor nazwy kwalifikowanej odnośnika wyjątkiem:

Od specjalizacje szablonów członkowskich dla funkcji konwersji nie zostaną znalezione przez wyszukiwania nazw, nie są one uważane kiedy używając-deklaracja określa funkcję konwersji (14.5.2).

Ale nie jest specjalizacją szablonu funkcji członka, więc nie należy brać pod

-1

Hmm ... GCC nie podoba się pierwszy albo. Kompiluje się, chyba że spróbujesz utworzyć instancję o numerze struct X z parametrem szablonu innym niż int. Jaki byłby sens X<double>::operator double()? Klasa B nie ma takiego operatora, ale spróbowalibyśmy go użyć.

Podsumowując: MSVC i clang próbują uprzedzić cię wcześniej (nawet jeśli nie robisz teraz niczego głupiego), podczas gdy gcc generuje błąd tylko wtedy, gdy spróbujesz stworzyć coś niepoprawnego. To nie kompiluje w gcc (niższych niż 5.3.0):

#include <iostream> 

struct B { operator int(); }; 

template<class T> 
struct X:B 
{ 
    using B::operator T; 
}; 

int main(int argc, char **argv) 
{ 
    X<char> x; 
    std::cout << "Hello!" << std::endl; 
    return 0; 
} 
+0

zmiana 'X x;' na 'X x;' ..........;) – 101010

+0

To nie znaczy, że GCC jest źle. Jeśli podasz operatora konwersji w szablonie 'B', a ty specjalizujesz się w' int', wszystkie kompilatory będą zadowolone, ale twój program nie skompiluje się (zawiedzie przy łączeniu) dla innego typu niż 'int' (z dowolnym kompilatorem). – Holt

+0

@ 101010 To jest dokładnie to, co napisałem: _To kompiluje, chyba że spróbujesz utworzyć instancję struktury X z parametrem szablonu innym niż 'int' ._ – Lehu

Powiązane problemy