2013-08-16 5 views
15

Когда взираю я два следующих перегрузок:универсальный опорный параметр vs const?

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

У меня есть гарантия, что f(x) всегда будут вызывать вторую функцию и никогда не приведут к неоднозначности. В некотором смысле вторая версия является общепринятой по сравнению с первой для одного аргумента независимо от его типа.

Теперь рассмотрит ситуацию, когда есть универсальный справочник и константная ссылка версия функции:

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

Мой вопрос: является их универсальным приоритет между этими двумя функциями, независимо от типа х (r-value reference, reference, cv-qualifiers, указатель ...), как в предыдущем случае? (и если да, то какой приоритет?)

+2

Я думаю, что это был [этот разговор] (http://www.youtube.com/watch?v=T5swP3dr190), который включил это. – chris

ответ

17

Между этими двумя функциями нет универсального приоритета. Они одинаково конкурируют в алгоритме разрешения перегрузки. В общем, так называемая «универсальная ссылка» выигрывает, если const T& не является точным совпадением, и побеждает 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 
} 

Хороший совет является никогда перегрузки, как это.

+0

Возможно, стоит упомянуть, какой из этих случаев (если есть) № 2 никогда не был кандидатом для начала. –

+0

@BenVoigt Если я что-то не хватает, обе перегрузки жизнеспособны во всех этих выражениях. – aschepler

+0

@aschepler: Я думаю, вы правы. Может быть, это 'T &&' vs 'T &', что заканчивается неожиданностью. –

 Смежные вопросы

  • Нет связанных вопросов^_^