C ++ pimpl idiom: implementation depending on template parameter

In this question, I unsuccessfully asked how to use a different implementation of pimpl depending on the template argument.

Perhaps this example better illustrates what I'm trying to do:

#include <iostream> template< int N, typename T > struct B { B() : c( new C< N > ) {} template< int M > struct C; C< N > *c; }; template< int N, typename T > template< int M > struct B< N, T >::C { int a[M]; }; // version 1 that doesn't work template< int N, typename T > template< > struct B< N, T >::C< 0 > { int a; }; // version 2 that doesn't work template< typename T > template< int M > struct B< 0, T >::C { int a; }; int main() { B< 0, float > b0; B< 1, int > b1; std::cout << "b0 = " << sizeof(b0.c->a) << std::endl; std::cout << "b1 = " << sizeof(b1.c->a) << std::endl; } 

It still fails if I try to specialize the C structure (above does not compile)

So can this be done?

I know a job like this:

 template< int M > struct D { int a[M]; }; template< > struct D<0> { int a; }; template< int N, typename T > template< int M > struct B< N, T >::C { D< M > helper; }; 

but if possible i would like to avoid this

0
source share
1 answer

What you are trying to do is not allowed in language.

ยง14.7.3.16 (FCD 2010-03-26) states:

In an explicit specialization, the declaration for a class member is a template or member template that appears in the namespace area, a member template and some of its class templates may remain unspecialized, except that the declaration should not explicitly specialize a class member template if its closing templates classes are not explicitly specialized. In such an explicit specialization declaration, a keyword template and then a list of template parameters should be provided instead of template <> before an explicit declaration of specialization member. The types of template parameters in template-parameter-list should be the same as specified in the primary template definition.

 [ Example: template <class T1> class A { template<class T2> class B { template<class T3> void mf1(T3); void mf2(); }; }; template <> template <class X> class A<int>::B { template <class T> void mf1(T); }; template <> template <> template<class T> void A<int>::B<double>::mf1(T t) { } template <class Y> template <> void A<Y>::B<double>::mf2() { } // ill-formed; B<double> is specialized but // its enclosing class template A is not โ€”end example ] 
+3
source

Source: https://habr.com/ru/post/927786/


All Articles