2016-03-27 22 views
5

Biorąc pod uwagę następujący prosty structo zmiennej liczbie argumentów szablonu priorytet konstruktor

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

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

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

Jaka jest gwarancja, że ​​A(T a) będzie wywoływana zamiast zmiennej liczbie argumentów konstruktora szablonów i dlaczego?

Odpowiedz

6

Sekcja w normie, której szukasz jest §14.8.2.4

Jeżeli A została przekształcona z pakietem funkcji i parametrów P nie jest paczka parametr typu odliczenie nie powiedzie się. W przeciwnym razie, stosując otrzymane typy P i A, odliczenie jest następnie wykonywane zgodnie z opisem w 14.8.2.5. Jeśli P jest pakietem parametrów funkcji, typ A każdego pozostałego typu parametru szablonu argumentu to w porównaniu z typem P identyfikatora-deklaratora pakietu parametrów funkcji. Każde porównanie powoduje wyprowadzenie argumentów szablonu dla kolejnych pozycji w pakietach parametrów szablonu rozszerzonych przez pakiet parametrów o funkcji . Jeśli dedukcja powiedzie się dla danego typu, typ z szablonu argumentu jest uważany za co najmniej tak specjalistyczny jak typ z szablonu parametru.

[przykład:

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 

- przykład end]

+1

14.8.2.4 jest porównaniem dwa szablony funkcyjnych zobaczyć, który jest bardziej wyspecjalizowana. Ale jedna z funkcji kandydata w tym przykładzie nie jest wcale szablonem funkcji. – aschepler

+0

@aschepler Mówisz, że kompilator nie musi być tak daleko, ponieważ posiadanie funkcji bez szablonu, która jest idealna, oznacza, że ​​nie trzeba nawet rozpoczynać rozdzielczości szablonu. Zgadzam się. Pojawi się kolejna sekcja, która to omawia. –

2

Z tego samego powodu f(const int&) pasuje lepiej niż f(const T&) gdy T można wywnioskować jak int: A(int) jest funkcją non-template i A(int, Ts...) z Ts... wyprowadzona jako pustą listę jest specjalizacja szablonu funkcji.

Powiązane problemy