Ответ 1
Комментарии @jrok в значительной степени объясняют вашу ошибку компилятора. Вложенные классы в целом и вложенные шаблоны классов, в частности, представляют собой пыльный угол языка, который можно легко избежать (принимая во внимание совет Саттера Напишите то, что вы знаете и знаете, что пишете).
Просто создайте namespace detail
, чтобы определить шаблоны классов SA
и SB
и их специализации, а затем определите псевдоним типа вложенного шаблона S
внутри A
и B
namespace detail {
template<class T, class = void>
class SA;
template<class T>
struct SA < T, typename std::enable_if< std::is_same< Y, T >::value >::type >
{
int i = 0;
};
template<class T>
struct SA < T, typename std::enable_if< std::is_same< X, T >::value >::type >
{
int i = 1;
};
template<class T>
class SB;
template<>
class SB < Y > {};
template<>
class SB < X > {};
}
struct A
{
template<class T>
using S = detail::SA<T>;
};
struct B
{
template<class T>
using S = detail::SB<T>;
};
Конечно, для этого случая это может показаться излишним, но если вы когда-либо захотите сделать шаблоны классов A
и B
сами, а specialize A
и B
, то вы можете специализировать только вложенные шаблоны классов если вы также специализируетесь на включении класса. Короче говоря, просто избегайте этих проблем в целом дополнительным уровнем косвенного времени.