идиома c ++ pimpl: реализация в зависимости от параметра шаблона - PullRequest
0 голосов
/ 24 марта 2011

В этот вопрос Я безуспешно спрашивал, как использовать разные реализации pimpl в зависимости от аргумента шаблона.

Может быть, этот пример лучше иллюстрирует то, что я пытаюсь сделать:

#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;
}

По-прежнему происходит сбой, если я пытаюсь специализировать структуру C (выше не компилируется)

Итак, можно ли это сделать?

Я знаю такую ​​работу:

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;
};

но если возможно, я бы хотел этого избежать

1 Ответ

3 голосов
/ 24 марта 2011

То, что вы пытаетесь сделать, не допускается языком.

§ 14.7.3.16 (FCD 2010-03-26) гласит:

В явной специализацииобъявление для члена шаблона класса или шаблона члена, который появляется в области пространства имен, шаблоне члена и некоторых из его шаблонов включающего класса, может оставаться неспециализированным, за исключением того, что объявление не должно явно специализировать шаблон члена класса, если его шаблоны заключающего классаявно не специализируется.В таком явном объявлении специализации вместо ключевого слова <>, предшествующего явному объявлению специализации члена, должен быть указан шаблон ключевого слова, за которым следует шаблон-списка параметров.Типы параметров шаблона в списке параметров шаблона должны быть такими же, как те, которые указаны в определении основного шаблона.

[ 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 ]
...