универсальная ссылка против постоянной ссылки?

Когда я рассматриваю две следующие перегрузки:

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);

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

15

Решение

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

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

17

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]