2016-03-27 4 views
5

Учитывая следующий простой structVARIADIC шаблон приоритета конструктор

template <typename T> 
struct A 
{ 
    A(T a) {} 

    template <typename ... Ts> 
    A(T a, Ts ... more) {} 
}; 

int main() 
{ 
    A<int> a(1); 
} 

Что является гарантией того, что A(T a) будет называться вместо VARIADIC конструктор шаблонов, и почему?

ответ

6

раздел в стандарте, который вы ищете является §14.8.2.4

Если А был преобразован из параметров функции пакета и P не является параметром пакета, тип вычет не удается. В противном случае, используя результирующие типы P и A, вычет затем выполняется, как описано в 14.8.2.5. Если P является пакетом параметров функций, тип A каждого оставшегося типа параметра шаблона аргумента равен по сравнению с типом P идентификатора-декларатора пакета параметров функции. Каждое сравнение выводит аргументы шаблона для последующих позиций в пакетах шаблонов параметров, расширенных пакетом параметров . Если для заданного типа выполняется успешное завершение вывода, тип из шаблона аргумента считается , чтобы быть как минимум таким же специализированным, как тип из шаблона параметра.

[Пример:

template<class... Args> void f(Args... args); // #1 
template<class T1, class... Args> void f(T1 a1, Args... args); // #2 
template<class T1, class T2> void f(T1 a1, T2 a2); // #3 
f(); // calls #1 
f(1, 2, 3); // calls #2 
f(1, 2); // calls #3; non-variadic template #3 is more 
// specialized than the variadic templates #1 and #2 

- конец пример]

+1

14.8.2.4 о сравнении двух шаблонов функций, чтобы увидеть, который является более специализированными. Но одна из функций-кандидатов в этом примере не является шаблоном функций вообще. – aschepler

+0

@aschepler Вы говорите, что компилятор не должен заходить так далеко, потому что наличие функции без шаблона, которая является идеальным сочетанием, означает, что даже не нужно начинать разрешение шаблона. Согласен. Там будет другой раздел, который охватывает это. –

2

По той же причине f(const int&) лучше подходит, чем f(const T&) когда T можно вывести, как int: A(int) функция не-шаблон и A(int, Ts...) с Ts... выведенной как пустой список является шаблоном функции специализации.