Zasadniczo częściowe zasady zamawiania powiedzieć, że przeciążenie dependent_type
jest bardziej wyspecjalizowany powodu, że brak wywnioskować kontekście.
Proces zamawiania funkcji szablonu polega na transformacji typów funkcji szablonu i wykonywaniu odliczeń szablonów po kolei, po przejściu z pierwszego szablonu (ten, który przyjmuje T
) do drugiego (ten, który przyjmuje dependent_type
), a następnie od drugiego do pierwszego.
Zasady są zbyt skomplikowane, aby można je było tutaj replikować, ale przeczytaj [temp.func.order]
i fragmenty, do których prowadzą linki, jeśli chcesz poznać szczegóły. Oto krótki uproszczenie:
Dla każdego parametru szablonu funkcji szablonu, tworzą unikalny rodzaj i zastąpić parametr z tym. Transformowane typy na ten przykład to:
void foo(UniqueType); //ignoring the SFINAE for simplicity
void foo(typename dependent_type<UniqueType>::type);
Następnie wykonać szablon odliczenia w dwóch kierunkach: po użyciu parametrów pierwszego szablonu jako argumenty do drugiego, a raz przy użyciu parametrów drugiego jako argumenty do pierwszy. Jest to podobne do wykonywania odliczenia na tych wywołań funkcji:
//performed against template <class T> void foo(typename dependent_type<T>::type);
foo(UniqueType{});
//performed against template <class T> void foo(T);
foo(dependent_type<UniqueType>::type{});
Realizując te potrącenia, staramy się rozpoznać, czy ktoś jest bardziej wyspecjalizowane przeciążenie potem drugą. Kiedy próbujemy pierwszego, dedukcja się nie udaje, ponieważ typename dependent_type<T>::type
jest kontekstem niewydechem. Na drugim, odliczenie uda bo dependent_type<UniqueType>::type
tylko UniqueType
, więc T
jest wyprowadzona do UniqueType
.
Od odliczenie udało począwszy od drugiego szablonu do pierwszego, drugi szablon jest brane jako bardziej wyspecjalizowane niż pierwszy. Ostateczny wynik jest taki, że rozdzielczość przeładowania preferuje drugi szablon dla foo<int>(1)
.
Myślę, że odpowiedź brzmi „b jest bardziej wyspecjalizowane, więc zawsze nazywa, jeśli to możliwe”, a powodem będzie leżeć gdzieś [tutaj] (http://en.cppreference.com/w/cpp/language/function_template) (zaczyna się w połowie strony). To trochę dla mnie jednak. – Quentin
Dobre pytanie. Dziękuję Ci.+1 – skypjack
Następnym razem polecam opublikowanie kodu jako pojedynczego fragmentu, aby ludzie mogli kopiować/wklejać jednorazowo, zamiast kopiować/wklejać dwa razy w celu wypróbowania kodu (i albo mieć odpowiedni zawierać dyrektywy lub demonstrować wybrane przeciążenie inaczej). –