специализируйте членский шаблон, не специализируя его родителя

Мне вложили шаблон класса в другом шаблоне. Частично специализация его легка: Я просто объявляю другого template< … > блок в его родителе.

Однако мне нужна другая частичная специализация, которая, оказывается, определяет все ее локальные аргументы шаблона. Это превращает его в явную специализацию. Явные специализации, по любой причине, должны быть в объеме пространства имен. Для объявления этого вне его родительского класса родитель должен быть назначен, который требует непустого списка аргумента шаблона. Это подразумевает частичную специализацию. Частичная специализация - то, что я делаю, и она, как предполагается, работает в произвольном внешнем объеме. Но и GCC и Comeau не удается определить шаблонный параметр в родительском назначении с частичной специализацией формальные аргументы.

template< class X > struct A {
    template< class Y > struct B; // initial declaration OK

    template< class Z >
    struct B< A< Z > > {}; // partial OK as long as there's a local arg

    template<> // ERROR: this syntax triggers explicit specialization
    struct B< int > {};
};

template<> // ERROR: can't nest template<>s here (why?)
template< class X > // ERROR: can't deduce X from type of A<X>::B<int> (why?)
struct A< X >::B< int > {};

(Я оставил весь свой нерабочий код внутри; прокомментируйте это соответственно, чтобы попытаться иметь смысл.)

10
задан Potatoswatter 5 January 2010 в 23:25
поделиться

4 ответа

Это незаконно в соответствии со стандартом C ++ 14.7.3 / 18:

.... объявление не должно явно определять член класса шаблон, если его включающие шаблоны классов не являются явно специализированными также.

9
ответ дан 3 December 2019 в 23:50
поделиться

Я не слишком часто использую вложенные классы. Моя основная жалоба заключается в том, что они имеют тенденцию к раздуванию кода класса, в который они вложены.

Поэтому я бы предложил другой обходной путь:

namespace detail
{
  template <class X, class Z> class BImpl;
  template <class X, class Z> class BImpl<X, A<Z> > {};
  template <class X> class BImpl<X,int> {};
}

template <class X>
class A
{
  template <class Z> struct B: BImpl<X,Z> {};
};

Просто обратите внимание, что он требует передачи X в качестве аргумента в BImpl, если вы когда-нибудь захотите также специализироваться на A. Забавно, что в этом случае я получаю только частичную специализацию!

.
4
ответ дан 3 December 2019 в 23:50
поделиться

По крайней мере, это работает в ВК 2010. Но я не могу написать def. of fun() для "int" вне объявления класса. EDIT: К сожалению, в g++ тоже есть проблемы с компиляциями. EDIT: Нижеприведенный код работал в VC 2010.

template<typename X>
class A
{
public:
    A()
    {

    }

    template<typename Y>
    struct B
    {
        void fun();
    };

    template<>
    struct B<int>
    {
        void fun()
        {
            cout << "Specialized version called\n";
        }
        //void fun();
    };



public:

    B<X> b;
};



template<typename X>
template<typename Y>
void A<X>::B<Y>::fun()
{
    cout << "templated version called\n";
}

int main()
{
   A<int> a;
    a.b.fun();
    A<float> a1;
    a1.b.fun();
}
0
ответ дан 3 December 2019 в 23:50
поделиться

Сложный материал. Ваш начальный код ICE VC10 Beta2, хорошо.

Во-первых, я думаю, у вас есть это наоборот:

template<> 
template< class X > 
struct A< X >::B< int > {};

X - это параметр шаблона для структуры A, а B - полностью специализированный, поэтому я думаю, что это должно быть так:

template< class X > 
template<> 
struct A< X >::B< int > {};

Но даже это не компилируется . Тем не менее, текст ошибки действительно полезен:

a.cpp a.cpp (11): error C3212: 'A :: B': явный специализация члена шаблона должен быть членом явного специализация a.cpp (8): см. объявление 'A :: B'

Похоже, что полностью специализировать B разрешено только в том случае, если вы также полностью специализируете A.

Edit : Хорошо, я получил ответ от кого-то, кто может авторитетно высказаться по этому поводу - перефразируя, это очень темная область в стандарте, и это открытый вопрос для Комитета C ++, чтобы очистить его («это» является явной специализацией членов шаблонов классов). В ближайшей перспективе совет: «Не делай этого».

0
ответ дан 3 December 2019 в 23:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: