[temp.arg.explicit] (original) (raw)
13 Templates [temp]
13.10 Function template specializations [temp.fct.spec]
13.10.2 Explicit template argument specification [temp.arg.explicit]
Template arguments can be specified when referring to a function template specialization that is not a specialization of a constructor template by qualifying the function template name with the list oftemplate-argument_s_in the same way astemplate-argument_s_are specified in uses of a class template specialization.
[Example 1:
template<class T> void sort(Array<T>& v);void f(Array<dcomplex>& cv, Array<int>& ci) { sort<dcomplex>(cv); sort<int>(ci); } andtemplate<class U, class V> U convert(V v);void g(double d) { int i = convert<int,double>(d); char c = convert<char,double>(d); }
— _end example_]
Template arguments shall not be specified when referring to a specialization of a constructor template ([class.ctor], [class.qual]).
A template argument list may be specified when referring to a specialization of a function template
- when a function is called,
- when the address of a function is taken, when a function initializes a reference to function, or when a pointer to member function is formed,
- in an explicit specialization,
- in an explicit instantiation, or
- in a friend declaration.
[Note 1:
A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced as an empty sequence of template arguments.
— _end note_]
If all of the template arguments can be deduced or obtained from default template-arguments, they may all be omitted; in this case, the empty template argument list <>itself may also be omitted.
[Example 2: template<class X, class Y> X f(Y);template<class X, class Y, class ... Z> X g(Y);void h() { int i = f<int>(5.6); int j = f(5.6); f<void>(f<int, bool>); f<void>(f<int>); int k = g<int>(5.6); f<void>(g<int, bool>); } — _end example_]
[Note 2:
An empty template argument list can be used to indicate that a given use refers to a specialization of a function template even when a non-template function ([dcl.fct]) is visible that would otherwise be used.
For example:template <class T> int f(T); int f(int); int k = f(1); int l = f<>(1);
— _end note_]
Template arguments that are present shall be specified in the declaration order of their corresponding template parameters.
[Example 3: template<class X, class Y, class Z> X f(Y,Z);template<class ... Args> void f2();void g() { f<int,const char*,double>("aa",3.0); f<int,const char*>("aa",3.0); f<int>("aa",3.0); f("aa",3.0); f2<char, short, int, long>(); } — _end example_]
Implicit conversions ([conv]) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template parameters that participate in template argument deduction.
[Note 3:
Template parameters do not participate in template argument deduction if they are explicitly specified.
For example,
template<class T> void f(T);class Complex { Complex(double);};void g() { f<Complex>(1); } — _end note_]
[Note 4:
Because the explicit template argument list follows the function template name, and because constructor templates ([class.ctor]) are named without using a function name ([class.qual]), there is no way to provide an explicit template argument list for these function templates.
— _end note_]
Template argument deduction can extend the sequence of template arguments corresponding to a template parameter pack, even when the sequence contains explicitly specified template arguments.
[Example 4: template<class ... Types> void f(Types ... values);void g() { f<int*, float*>(0, 0, 0); } — _end example_]