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.
Woah, ten ostatni jest jeszcze bardziej interesujący - będę o tym pamiętać, dzięki! –