Учитывая следующий фрагмент кода, почему функция 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
Потому что тот без const
требует меньше преобразований. Когда компилятор выбирает перегрузку, он сначала ищет те, которые точно соответствуют, затем он проходит серию преобразований в определенном порядке, и первая найденная — используемая.
В этом примере sc
это SomeClass<char>*&
, Сначала компилятор пытается найти точное совпадение, а поскольку его нет, он пытается удалить &
, Так как он находит то, он прекращает поиск и не добавляет const
который позволил бы ему видеть другого.
foo(T)
точное совпадение аргумента с T
знак равно SomeClass<T>*
,
foo(const SomeClass<T>*)
требует преобразования квалификации (чтобы добавить const
Классификатор).
Точное совпадение лучше, чем совпадение, которое требует какого-либо преобразования, даже если это просто квалификационное преобразование.