2013-05-26 13 views
7

Poniższy kod świetnie się komplikuje z gcc i clang.Dlaczego te przeciążenia nie są niejednoznaczne?

template <typename T> 
struct identity 
{ 
    typedef T type; 
}; 

template <typename T> 
void foo(typename identity<T>::type); 

template <typename T> 
void foo(T); 

int main() 
{ 
    foo<int>(0); 
} 

Wygląda rozdzielczości przeciążenie wybiera pierwszy przeciążenie (jednej identity<T>::type).

Czy ktoś mógłby wyjaśnić, dlaczego przeciążenia nie są niejednoznaczne? O ile mi wiadomo, jedyną różnicą między nimi jest to, że argumentem pierwszego jest nie wywnioskowany kontekst, a argument drugiego nie jest, ale ponieważ dostarczam argument szablonu jawnie, Nie rozumiem, dlaczego to ma znaczenie.

+0

Interesujące. Oczywiście druga funkcja zostałaby wybrana, gdyby włączono odliczanie typu, nie tworząc jawnie 'foo (0)', ale 'foo (0)' zamiast (Bez dedukcji dla funkcji meta tożsamości)[email protected] Prowl: Nie chcę kwestionować twojej odpowiedzi, zaznacz, że twoje rozumowanie nie jest tak oczywiste, jak mogłoby się wydawać. Ustaw parametr foo jako wartość domyślną i wywołaj 'foo ()' bez parametru. Twoja argumentacja powinna nadal obowiązywać, ale teraz przeciążenia są niejednoznaczne, tak jak oczekiwał HighCommander4. Jawne tworzenie szablonów funkcji jest skomplikowane. –

Odpowiedz

7

Obydwa przeciążenia są wykonalne, ale pierwszy jest bardziej wyspecjalizowany niż ten drugi, a zatem jest wybierany przez rozdzielczość przeciążenia.

zgodnie z pkt 13.3.3/1 o C++ 11 Standardu rozdzielczości przeciążeniem:

[...] realną funkcja F1 określa się lepiej niż funkcja innej realnej funkcji F2 jeśli dla wszystkich argumentów i, ICSi(F1) nie jest gorszy niż ICSi(F2) sekwencja konwersji, a następnie

- jakiegoś argumentu j, ICSj(F1) jest lepiej niż ICSj(F2) sekwencja konwersji, lub, jeśli nie, że

- kontekst jest inicjalizacją przez konwersję zdefiniowaną przez użytkownika (patrz 8.5, 13.3.1.5 i 13.3.1.6) i standardową sekwencję konwersji typu F12 do typu docelowego (tj. Typ Inicjowana jednostka) jest lepszą sekwencją konwersji niż standardowa sekwencja konwersji z typu zwrotu z F2 do typu docelowego. [...] lub, jeśli nie, że

- F1 jest funkcją non-template i F2 jest funkcją szablon specjalizacji, lub, jeśli nie, że

- F1 i F2 funkcyjne są specjalizacje szablonu , a szablon funkcji dla F1 jest bardziej wyspecjalizowany niż szablon dla F2 zgodnie z zasadami porządkowania częściowego opisanymi w 14.5.6.2.

proces ustalania, który z dwóch szablonów funkcyjnych jest bardziej wyspecjalizowane niż inne przedstawiono w pkt 14.5.6.2/2:

częściowe wybiera zamawiania, który z dwóch szablonów funkcji jest bardziej wyspecjalizowane niż drugi przekształcając kolejno każdy szablon (patrz następny akapit) i wykonując dedukcję argumentu szablonu za pomocą funkcji typu . Proces odliczenia określa, czy jeden z szablonów jest bardziej wyspecjalizowany niż drugi. Jeśli więc , tym bardziej wyspecjalizowanym szablonem jest ten wybrany w procesie częściowego zamawiania.

+0

Ma sens, dzięki! (Intuicyjnie myślałem o "bardziej wyspecjalizowanym niż" znaczeniu "dotyczy mniejszego zbioru typów danych wejściowych", co jest moim zdaniem intencją, ale widzę, że techniczna definicja tego terminu nie oznacza dokładnie tego.) – HighCommander4

+0

@ HighCommander4: Cieszę się, że to pomogło :) Twoja intuicja "stosuje się do mniejszego zestawu typów danych" ma sens, chociaż - jak zauważyłeś - może to czasem wprowadzać w błąd –

Powiązane problemy