Search code examples
c++templatesscopec++14default

What are the scopes of default template arguments?


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().


Solution

  • 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]