Search code examples
c++templatesg++gnutemplate-meta-programming

Nested template classes: Parameter default value not accepted


This compiles:

class A {
public:
  template <int, int> class B;
};

template <int y, int z = y>
class A::B {
};

int main() {}

This doesn’t:

template <int x>
class A {
public:
  template <int, int> class B;
};

template <int x>
template <int y, int z = y>
class A<x>::B {
};

int main() {}

g++ main.cpp says: (version 9.1.0)

main.cpp:24:13: error: default argument for template parameter for class enclosing ‘class A<x>::B<<anonymous>, <anonymous> >’
   24 | class A<x>::B {
      |             ^

What’s wrong?


Solution

  • Default parameter needs to be in the declaration:

    template <int x>
    class A {
    public:
      template <int y, int = y> class B;
    };
    
    template <int x>
    template <int y, int z>
    class A<x>::B {
    };
    
    int main() {
        A<1>::B<2> b;
    }
    

    Default parameters are not allowed in the out-of-class definition of a member of a class template (they have to be provided in the declaration inside the class body). Note that member templates of non-template classes can use default parameters in their out-of-class definitions (see GCC bug 53856)

    (https://en.cppreference.com/w/cpp/language/template_parameters)