kalj
kalj

Reputation: 1472

Incorrect instantiation of template specialization

In the following code, I try to specialize the class A for the base case when the template parameter T has value B<m>.

#include <array>
#include <iostream>

template <std::size_t m>
struct B
{
  std::array<double,m> arr;
};


template <std::size_t n, typename T>
struct A
{
  std::array<T,n> arr;
  const static int inner_dim = T::inner_dim;
};

template <std::size_t n >
template <std::size_t m>
struct A<n,B<m>>
{
  std::array<B<m>,n> arr;
  const static int inner_dim = m;
};


int main(int argc, char *argv[])
{
  A<5,A<4,B<3>>> a;
  std::cout << a.inner_dim << std::endl;

  A<5,B<4>> b;
  std::cout << b.inner_dim << std::endl;

  return 0;
}

However, at the instantiations in main, I get the following error, when I compile with g++ 5.4:

$ g++ -Wall --std=c++11 specialization.cc 
specialization.cc: In instantiation of ‘const int A<4ul, B<3ul> >::inner_dim’:
specialization.cc:15:20:   required from ‘const int A<5ul, A<4ul, B<3ul> > >::inner_dim’
specialization.cc:30:18:   required from here
specialization.cc:15:20: error: ‘inner_dim’ is not a member of ‘B<3ul>’
   const static int inner_dim = T::inner_dim;
                    ^
specialization.cc: In instantiation of ‘const int A<5ul, B<4ul> >::inner_dim’:
specialization.cc:33:18:   required from here
specialization.cc:15:20: error: ‘inner_dim’ is not a member of ‘B<4ul>’

It seems only the general definition is used, never the specialization. How can I ensure that the right specialization is instantiated?

Upvotes: 2

Views: 84

Answers (1)

w1ck3dg0ph3r
w1ck3dg0ph3r

Reputation: 1011

My guess is

template <std::size_t n >
template <std::size_t m>
struct A<n,B<m>>

should be

template <std::size_t n, std::size_t m>
struct A<n,B<m>>

Upvotes: 6

Related Questions