2013-05-31 11 views
10

Ku mojemu zdziwieniu ten program kompiluje zarówno MSCV i GCC:nazwa Metoda taka sama jak nazwa metody szablonu w C++

class A 
{ 
public: 
    int add() { return 0; } 
    template<typename T> 
    T add() { return T(); } 
}; 

int main() { 
    A a; 
    a.add(); 
    a.add<int>(); 
    return 0; 
} 

Oczywiście, ze względu na fakt, że rodzaj metody matrycy nie można wywnioskować i potrzebuje być jednoznacznie stwierdzone, więc sytuacja nie jest dwuznaczna - nadal wydaje się nieco zacieniona - gdyby była to metoda niesformatowana, która byłaby oczywiście niepoprawna.

Próbowałem googling i przeglądając ostatnią wersję standardu, ale nie mogłem znaleźć odpowiedzi - jest to samo nazewnictwo metody szablonów i normalnej metody, które różnią się tylko typem zwrotnym legal w C++, lub są kompilatory są po prostu przyzwalające?

Odpowiedz

10

To zawsze było legalne w C++.

14.5.6/2:

Wzór funkcja może być przeciążona z innych szablonów funkcyjnych i w normalnym (bez matrycy). Zwykła funkcja nie jest powiązana z szablonem funkcji (tzn. Nigdy nie jest uważana za specjalizację), nawet jeśli ma taką samą nazwę i typ, jak potencjalnie wygenerowana specjalizacja szablonu funkcji.

Podczas korzystania ze składni "identyfikator szablonu", takiej jak add<int>, uwzględniane są tylko funkcje szablonu z wystarczającą liczbą parametrów szablonu. Tak więc a.add<int>() nie sprawdza nawet, czy pasuje non-template add.

Gdy identyfikator określa zarówno funkcję prostą, jak i szablon funkcji, kompilator spróbuje wywnioskować argumenty szablonu dla szablonu funkcji, aby uzyskać specjalizację funkcji szablonu. Następnie wszystkie proste funkcje i wszystkie specjalizacje funkcji szablonu są porównywane przez zwykłą logikę przeciążania funkcji. [Zobacz 13.3.1/7.]

W tym przykładzie wywołanie a.add() nie może wyprowadzić argumentu szablonu T dla wersji szablonu. Tak więc jedyną realną funkcją jest przeciążenie bez szablonu.

Istnieje również inna zasada, która pojawia się w podobnej sytuacji: jeśli funkcja bez szablonu i funkcja szablonu byłyby w przeciwnym razie niejednoznacznym przeciążeniem, funkcja bez szablonu wygrywa. [Zasada ta znajduje się w sekcji 13.3.3, w środku definicji co sprawia, że ​​jedna funkcja lepiej niż inny dla danego zbioru argumentów.]

class B 
{ 
public: 
    int f(int n) { return n+1; } 

    template<typename T> 
    T f(T n) { return n; } 
}; 

int main() { 
    B b; 
    b.f(1);  // both are viable, non-template wins 
    b.f<int>(1); // only the template is viable 
    return 0; 
} 

Ma to sens, ponieważ szablon może być nadal używany przez inne specjalizacje lub jawnie za pomocą kątowników <>. Przeciążanie szablonu funkcji za pomocą funkcji innej niż szablon jest podobne do dodawania wyraźnej specjalizacji, ale przy mniejszej liczbie bólów głowy.

+0

Woah, ten ostatni jest jeszcze bardziej interesujący - będę o tym pamiętać, dzięki! –

Powiązane problemy