The standard (§14.1) Template parameters says:
A template-parameter of a template template-parameter is permitted to have a default template-argument.
Now consider following code :
#include <iostream>
using namespace std;
struct A {};
struct B {};
template<typename T = A>
struct X;
template<>
struct X<A> {
static void f() { cout << 1 << endl; }
};
template<>
struct X<B> {
static void f() { cout << 2 << endl; }
};
template< template<typename T = B> class C>
void g() {
C<>::f();
}
int main() {
g<X>();
}
It's output is:
out put :2
In this case, the template template-parameter is C
.
But I don't understand why C<B>::f()
is called inside g()
.
This declaration
template< template<typename T = B> class C>
void g() {
C<>::f();
}
is equivalent to
template< template<typename T = B> class C>
void g() {
C<B>::f();
}
Thus this call
g<X>();
is equivalent to the call of the function
void g() {
X<B>::f();
}
The paragraph #14.1.14 of the C++ Standard contains corresponding examples
14 A template-parameter of a template template-parameter is permitted to have a default template-argument. When such default arguments are specified, they apply to the template template-parameter in the scope of the template template-parameter. [Example:
template <class T = float> struct B {};
template <template <class TT = float> class T> struct A {
inline void f();
inline void g();
};
template <template <class TT> class T> void A<T>::f() {
T<> t; // error - TT has no default template argument
}
template <template <class TT = char> class T> void A<T>::g() {
T<> t; // OK - T<char>
}
—end example]
Think about what would happen without default template template parameter for g():
template< template<typename T> class C>
void g() {
C<>::f();
}
would be ill-formed as the use of C would require a template parameter inside the definition of g(). Now that you provided B as a default, the definition of template g() is well formed and the default for the template template parameter of X is irrelevant.
I think this is covered by N4567 14.1/14
A template-parameter of a template template-parameter is permitted to have a default template-argument. When such default arguments are specified, they apply to the template template-parameter in the scope of the template template-parameter. [Example:
template <class T = float> struct B {};
template <template <class TT = float> class T>
struct A { inline void f(); inline void g(); };
template <template> <class TT> class T> void A<T>::f() {
T<> t; // error - TT has no default template argument
}
template <template <class TT = char> class> T> void A<T>::g() {
T<> t; // OK - T<char>
}
-- end example]
So the default template parameter of a template template parameter applies only in the scope where the default parameter is declared.
In the examples it is even switching the default template parameter for the template template parameter between the member function declaration and the member function definition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With