Специализация внутреннего шаблона с параметрами по умолчанию

У меня проблемы со специализацией внутреннего шаблона, когда все его параметры известны. Вот пример:

template < typename T0 >
struct outer
{
    template < typename T1 = void, typename T2 = void >
    struct inner
    {
        typedef T1 type;
    };
};
template < typename T0 >
template < typename T1 >
struct outer<T0>::inner<double,T1> { typedef int type; };

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

template < typename T0 >
template < >
struct outer<T0>::inner<double,void> { typedef int type; };

В связи с этим я получаю сообщение об ошибке: «Недопустимая явная специализация перед токеном‘> ’... включающие шаблоны классов не являются явно специализированными ... параметры шаблона не используются в частичной специализации: ... T0». Не уверен, что здесь происходит WTAF.

Я тоже пробовал это:

template < typename T0 >
struct outer<T0>::inner<double,void> { typedef int type; };

Я ожидал, что это не удастся, и сообщение об ошибке неудивительно. Это было: "слишком мало списков-параметров-шаблонов".

Итак, как правильно это сделать? Я, конечно, могу обойти это, но если мне это не нужно, я бы предпочел этого не делать.


person Edward Strange    schedule 16.06.2013    source источник
comment
связанные: stackoverflow.com/questions/9219157/   -  person Nate Kohl    schedule 16.06.2013
comment
Хм ... Я искал, но этого не было. Перед этим не должны были приносить в жертву коз правильного вида.   -  person Edward Strange    schedule 16.06.2013


Ответы (1)


Это не разрешено. Вы не можете полностью специализировать член шаблона класса, который сам не был полностью специализирован.

Согласно параграфу 14.7.16 стандарта C ++ 11:

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

Кроме того, в пункте 14.7.3 / 15 стандарта C ++ 11 говорится:

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

template<class T1> class A {
     template<class T2> class B {
         void mf();
     };
};
template<> template<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();

- конечный пример]

person Andy Prowl    schedule 16.06.2013
comment
Это не функция-член, но я полагаю, что то же правило применяется к вложенным типам? - person Nate Kohl; 16.06.2013
comment
Предполагая, что Нейт прав. Вы можете процитировать главу / стих? 03 лучше, но 11 подойдет. - person Edward Strange; 16.06.2013
comment
@CrazyEddie: Да, я ищу цитату - person Andy Prowl; 16.06.2013
comment
@CrazyEddie: Я добавил ссылку на стандарт - person Andy Prowl; 16.06.2013
comment
Может, 14.7.3 / 16 подойдет больше? (... за исключением того, что объявление не должно явно специализировать шаблон члена класса, если его включающие шаблоны класса также не являются явно специализированными.) - person Nate Kohl; 16.06.2013
comment
Не уверен насчет 11, но 03 имеет 14.7.3 / 18, и в нем явно указано, что то, что я пытаюсь сделать, неправильно сформировано. Также указывается, ... за исключением того, что объявление не должно явно специализировать шаблон члена класса, если его включающие шаблоны класса также не являются явно специализированными. Круто, ответ принят. - person Edward Strange; 16.06.2013
comment
@NateKohl: Да, верно. Я как раз собирался это добавить, спасибо, что упомянули об этом! - person Andy Prowl; 16.06.2013
comment
@ Энди - ну, это означает, что мой хакер необходим, а не просто недоразумение с моей стороны: P Спасибо. - person Edward Strange; 16.06.2013