2013-08-16 15 views
15

Kiedy rozważyć dwie następujące przeciążeń:odwołanie do uniwersalnego odniesienia do priorytetu odniesienia?

template <class... T> void f(const T&... x); 
template <class T> void f(const T& x); 

mam gwarancję, że f(x) zawsze zadzwonić drugą funkcję i nigdy nie będzie prowadzić do niejasności. W pewnym sensie druga wersja jest uniwersalnie traktowana priorytetowo w porównaniu z pierwszą dla jednego argumentu bez względu na jego typ.

Rozważmy teraz sytuację, w której istnieje uniwersalna odniesienia i const wersje referencyjne funkcji:

template <class T> void f(T&& x); 
template <class T> void f(const T& x); 

Moje pytanie brzmi: jest ich uniwersalny pierwszeństwo pomiędzy tymi dwoma funkcjami, niezależnie od typu X (r-wartość referencyjna, referencyjna, kwalifikatory cv, wskaźnik ...) jak w poprzednim przypadku? (a jeśli tak, jaki jest priorytet?)

+2

Myślę, że to była [ta rozmowa] (http://www.youtube.com/watch?v=T5swP3dr190), która obejmowała to. – chris

Odpowiedz

17

Nie ma uniwersalnego priorytetu między tymi dwiema funkcjami. Równocześnie rywalizują w algorytmie rozwiązywania przeciążenia. Ogólnie rzecz biorąc, tak zwane "uniwersalne odniesienie" wygrywa, chyba że const T& jest dokładnym dopasowaniem i tam wygrywa const T&.

struct A {}; 

int 
main() 
{ 
    f(std::declval<A>()); // calls f<A>(A&&), #1 
    f(std::declval<const A>()); // calls f<const A>(const A&&), #1 
    f(std::declval<A&>()); // calls f<A&>(A&), #1 
    f(std::declval<A&&>()); // calls f<A>(A&&), #1 
    f(std::declval<const A&&>()); // calls f<const A>(const A&&), #1 
    f(std::declval<const A&>()); // calls f<A>(const A&), #2 
} 

Dobra rada jest nigdy przeciążeniem tak.

+0

Warto wspomnieć, który z tych przypadków (jeśli taki był) # 2 nigdy nie był kandydatem na początek. –

+0

@BenVoigt O ile czegoś nie brakuje, oba przeciążenia są wykonalne we wszystkich tych wyrażeniach. – aschepler

+0

@aschepler: Myślę, że masz rację. Może to jest "T &&" a "T &", co w końcu jest zaskakujące. –

Powiązane problemy