2016-09-04 4 views
6

Следующий код prints "func 2".Разрешение перегрузки и явные аргументы шаблона

Почему компилятор рассматривает второй шаблон как лучшее совпадение в присутствии явных (не выводимых) аргументов шаблона? Почему нет двусмысленности?

Буду признателен за цитаты из стандарта C++.

#include <iostream> 

template<class T> 
struct identity 
{ 
    typedef T type; 
}; 

template<class T> 
void func(T) 
{ 
    std::cout << "func 1\n"; 
} 

template<class T> 
void func(typename identity<T>::type) 
{ 
    std::cout << "func 2\n"; 
} 

int main() 
{ 
    func<int>(1);  
} 

ответ

3

Оба кандидата является жизнеспособным и принимают одинаковые аргументы, поэтому процесс разрешения перегрузки возвращается к последнему тай-брейку: частичное упорядочение шаблонов функциев [temp.func.order].

Правило состоит в том, что мы синтезируем новый тип для каждого параметра типа шаблона и пытаемся выполнить вычитание друг над другом перегрузки. Для 1 мы синтезируем тип Unique1, который не дает вычетов на 2, потому что T не является выведенным контекстом. Для 2 мы синтезируем тип Unique2, который успешно выводит T = typename identity<Unique2>::type. Поскольку вычет преуспевает в одном направлении, а не в другом, что делает 2 более специализированным, чем 1, поэтому это предпочтителен.

Обратите внимание, что правила частичного заказа шаблона несколько неполны в стандарте. Если вы просто добавите еще один аргумент типа T, предпочтение flips.

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