Загадка поиска имен шаблонных функций (ADL)

Учитывая следующий фрагмент кода, почему функция Generic вызывается вместо более конкретной функции на основе SomeClass?

template <typename T>
class SomeClass
{
};

template <typename T>
void foo(T)
{
std::cout << "foo() Generic - Undesired function\n";
}

template <typename T>
void foo(const SomeClass<T>*)
{
std::cout << "foo() SomeClass<T> - Desired function\n";
}int main()
{
SomeClass<char>* sc = new SomeClass<char>();
foo(sc);
return 0;
}

Примечание: если бы я удалил const изvoid foo(const SomeClass<T>*)«определение, вызывается нужная функция. Я также попытался переставить foo, хотя это не оказало никакого влияния. Если возможно, некоторые могут вызвать соответствующие области в стандарте, которые описывают этот конкретный сценарий ADL.

С const: http://ideone.com/DIchLl

Без const: http://ideone.com/Iam4LV

С const (1-й): http://ideone.com/W6PoJw

2

Решение

Потому что тот без const требует меньше преобразований. Когда компилятор выбирает перегрузку, он сначала ищет те, которые точно соответствуют, затем он проходит серию преобразований в определенном порядке, и первая найденная — используемая.

В этом примере sc это SomeClass<char>*&, Сначала компилятор пытается найти точное совпадение, а поскольку его нет, он пытается удалить &, Так как он находит то, он прекращает поиск и не добавляет const который позволил бы ему видеть другого.

2

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

foo(T) точное совпадение аргумента с T знак равно SomeClass<T>*,

foo(const SomeClass<T>*) требует преобразования квалификации (чтобы добавить const Классификатор).

Точное совпадение лучше, чем совпадение, которое требует какого-либо преобразования, даже если это просто квалификационное преобразование.

2