Reputation: 8539
Given the following simple struct
template <typename T>
struct A
{
A(T a) {}
template <typename ... Ts>
A(T a, Ts ... more) {}
};
int main()
{
A<int> a(1);
}
What is the guarantee that A(T a)
will be called instead of the variadic template constructor, and why?
Upvotes: 5
Views: 401
Reputation: 69902
The section in the standard you're looking for is §14.8.2.4
If A was transformed from a function parameter pack and P is not a parameter pack, type deduction fails. Otherwise, using the resulting types P and A, the deduction is then done as described in 14.8.2.5. If P is a function parameter pack, the type A of each remaining parameter type of the argument template is compared with the type P of the declarator-id of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template.
[ Example:
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
— end example ]
Upvotes: 6
Reputation: 72431
The same reason f(const int&)
is a better match than f(const T&)
when T
can be deduced as int
: A(int)
is a non-template function and A(int, Ts...)
with Ts...
deduced as the empty list is a function template specialization.
Upvotes: 2