The template<> prefix indicates that the following template declaration takes no template parameters. The declaration_name is the name of a previously declared template. Note that you can forward-declare an explicit specialization so the declaration_body is optional, at least until the specialization is referenced.
using namespace std;
template<class T = float, int i = 5> class A
{
public:
A();
int value;
};
template<> class A<> { public: A(); };
template<> class A<double, 10> { public: A(); };
template<class T, int i> A<T, i>::A() : value(i) {
cout << "Primary template, "
<< "non-type argument is " << value << endl;
}
A<>::A() {
cout << "Explicit specialization "
<< "default arguments" << endl;
}
A<double, 10>::A() {
cout << "Explicit specialization "
<< "<double, 10>" << endl;
}
int main() {
A<int,6> x;
A<> y;
A<double, 10> z;
}
Primary template non-type argument is: 6
Explicit specialization default arguments
Explicit specialization <double, 10>
This example declared two explicit specializations for the primary template (the template which is being specialized) class A. Object x uses the constructor of the primary template. Object y uses the explicit specialization A<>::A(). Object z uses the explicit specialization A<double, 10>::A().
template<class T> class A;
template<> class A<int>;
template<> class A<int> { /* ... */ };
The primary template is not defined, but the explicit
specialization is.template<class T> class X { };
template<> class X<char>;
X<char>* p;
X<int> i;
// X<char> j;
The compiler does not allow the declaration X<char>
j because the explicit specialization of X<char> is
not defined.template<> class A<int>;
template<class T> class A;
An explicit specialization is in the same namespace as
the definition of the primary template.template<class T> class A {
public:
void f(T);
};
template<> class A<int> {
public:
int g(int);
};
int A<int>::g(int arg) { return 0; }
int main() {
A<int> a;
a.g(1234);
}
The explicit specialization A<int> contains
the member function g(), which the primary template
does not.template<class T> class A { };
void f() { A<int> x; }
template<> class A<int> { };
int main() { f(); }
The compiler will not allow the explicit
specialization template<> class A<int> { }; because
function f() uses this specialization (in the construction
of x) before the specialization.template<class T> class X { };
template<class T> void f(X<T>);
template<> void f(X<int>);
The explicit specialization template<>
void f(X<int>) is equivalent to template<>
void f<int>(X<int>). template<class T> void f(T a) { };
template<> void f<int>(int a = 5) { };
template<class T> class X {
void f(T a) { }
};
template<> void X<int>::f(int a = 10) { };
template<class T> class X {
public:
static T v;
static void f(T);
};
template<class T> T X<T>::v = 0;
template<class T> void X<T>::f(T arg) { v = arg; }
template<> char* X<char*>::v = "Hello";
template<> void X<float>::f(float arg) { v = arg * 2; }
int main() {
X<char*> a, b;
X<float> c;
c.f(10);
}
This code explicitly specializes the initialization of
static data member X::v to point to the string "Hello" for
the template argument char*. The function X::f() is
explicitly specialized for the template argument float.
The static data member v in objects a and b point
to the same string, "Hello". The value of c.v is
equal to 20 after the call function call c.f(10).#include <iostream>
using namespace std;
template<class T> class X {
public:
template<class U> class Y {
public:
template<class V> void f(U,V);
void g(U);
};
};
template<class T> template<class U> template<class V>
void X<T>::Y<U>::f(U, V) { cout << "Template 1" << endl; }
template<class T> template<class U>
void X<T>::Y<U>::g(U) { cout << "Template 2" << endl; }
template<> template<>
void X<int>::Y<int>::g(int) { cout << "Template 3" << endl; }
template<> template<> template<class V>
void X<int>::Y<int>::f(int, V) { cout << "Template 4" << endl; }
template<> template<> template<>
void X<int>::Y<int>::f<int>(int, int) { cout << "Template 5" << endl; }
// template<> template<class U> template<class V>
// void X<char>::Y<U>::f(U, V) { cout << "Template 6" << endl; }
// template<class T> template<>
// void X<T>::Y<float>::g(float) { cout << "Template 7" << endl; }
int main() {
X<int>::Y<int> a;
X<char>::Y<char> b;
a.f(1, 2);
a.f(3, 'x');
a.g(3);
b.f('x', 'y');
b.g('z');
}
See the output of the above program: Template 5
Template 4
Template 3
Template 1
Template 2
Inline namespace definitions are namespace definitions with an initial inline keyword. Members of an inline namespace can be explicitly instantiated or specialized as if they were also members of the enclosing namespace. For more information, see Inline namespace definitions (C++11).