[temp.arg.explicit]

# 13 Templates [[temp]](./#temp)

## 13.10 Function template specializations [[temp.fct.spec]](temp.fct.spec#temp.arg.explicit)

### 13.10.2 Explicit template argument specification [temp.arg.explicit]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7566)

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 of[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* in the same way as[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* are specified in uses of a class template specialization[.](#1.sentence-1)

[*Example [1](#example-1)*:

template<class T> void sort(Array<T>& v);void f(Array<dcomplex>& cv, Array<int>& ci) { sort<dcomplex>(cv); // sort(Array<dcomplex>&) sort<int>(ci); // sort(Array<int>&)} andtemplate<class U, class V> U convert(V v);

void g(double d) {int i = convert<int,double>(d); // int convert(double)char c = convert<char,double>(d); // char convert(double)}

â *end example*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7595)

Template arguments shall not be specified
when referring to a specialization of
a constructor template ([[class.ctor]](class.ctor "11.4.5 Constructors"), [[class.qual]](class.qual "6.5.5.2 Class members"))[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7600)

A template argument list may be specified when referring to a specialization
of a function template

- [(3.1)](#3.1)

when a function is called,

- [(3.2)](#3.2)

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,

- [(3.3)](#3.3)

in an explicit specialization,

- [(3.4)](#3.4)

in an explicit instantiation, or

- [(3.5)](#3.5)

in a friend declaration[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7617)

Trailing template arguments that can be deduced ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) or
obtained from default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* may be omitted from the list of explicit [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*[.](#4.sentence-1)

[*Note [1](#note-1)*:

A trailing template parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")) not otherwise deduced will be
deduced as an empty sequence of template arguments[.](#4.sentence-2)

â *end note*]

If all of the template arguments can be
deduced or obtained from default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*,
they may all be omitted;
in this case, the empty template argument list <> itself may also be omitted[.](#4.sentence-3)

[*Example [2](#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); // Y deduced as doubleint j = f(5.6); // error: X cannot be deduced f<void>(f<int, bool>); // Y for outer f deduced as int (*)(bool) f<void>(f<int>); // error: f<int> does not denote a single function template specializationint k = g<int>(5.6); // Y deduced as double; Z deduced as an empty sequence f<void>(g<int, bool>); // Y for outer f deduced as int (*)(bool),// Z deduced as an empty sequence} â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7646)

[*Note [2](#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]](dcl.fct "9.3.4.6 Functions")) is visible that would otherwise be used[.](#5.sentence-1)

For example:template <class T> int f(T); // #1int f(int); // #2int k = f(1); // uses #2int l = f<>(1); // uses #1

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7660)

Template arguments that are present shall be specified in the declaration
order of their corresponding template parameters[.](#6.sentence-1)

The template argument list shall not specify more[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* than there are corresponding[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* unless one of the [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* declares a template
parameter pack[.](#6.sentence-2)

[*Example [3](#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); // Z deduced as double f<int>("aa",3.0); // Y deduced as const char*; Z deduced as double f("aa",3.0); // error: X cannot be deduced f2<char, short, int, long>(); // OK} â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7683)

Implicit conversions ([[conv]](conv "7.3 Standard conversions")) 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[.](#7.sentence-1)

[*Note [3](#note-3)*:

Template parameters do not participate in template argument deduction if
they are explicitly specified[.](#7.sentence-2)

For example,

template<class T> void f(T);

class Complex { Complex(double);};

void g() { f<Complex>(1); // OK, means f<Complex>(Complex(1))} â *end note*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7706)

[*Note [4](#note-4)*:

Because the explicit template argument list follows the function
template name, and because
constructor templates ([[class.ctor]](class.ctor "11.4.5 Constructors")) are named without using a
function name ([[class.qual]](class.qual "6.5.5.2 Class members")), there is no way to provide an explicit
template argument list for these function templates[.](#8.sentence-1)

â *end note*]

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7715)

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[.](#9.sentence-1)

[*Example [4](#example-4)*: template<class ... Types> void f(Types ... values);

void g() { f<int*, float*>(0, 0, 0); // Types deduced as the sequence int*, float*, int} â *end example*]
