类范围中的类模板特化?

Mon*_*omy 11 c++ templates nested-class specialization

为什么A中的专业化S和B中的S不是?

(如果B未被注释掉)GCC 4.8.1:错误:非命名空间范围'class B'中的显式特化

#include <type_traits>
#include <iostream>

class Y {};
class X {};

struct A {
  template<class T, class = void>
  class S;

  template<class T>
  struct S < T, typename std::enable_if< std::is_same< Y, T >::value >::type > 
  {
    int i = 0;
  };

  template<class T>
  struct S < T, typename std::enable_if< std::is_same< X, T >::value >::type > 
  {
    int i = 1;
  };
};

/*
class B
{
    template<class T>
    class S;

    template<>
    class S < Y > {};

    template<>
    class S < X > {};
};
*/


int main()
{
    A::S< X > asd;
    std::cout << asd.i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

在coliru:B评论说

在coliru:与B(错误)

Tem*_*Rex 11

@jrok的评论几乎解释了你的编译器错误.一般来说,嵌套类,特别是嵌套类模板,是你可以轻松避免的语言的一个尘土飞扬的角落(记住 Sutter的建议" 写下你知道的,知道你写的是什么 ").

简单地做一个namespace detail定义你的类模板SA,并SB与他们的专长,然后定义一个嵌套的模板类型别名S内都AB

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>;
};
Run Code Online (Sandbox Code Playgroud)

当然,这种情况下,它可能看起来矫枉过正,但如果你想使AB类模板本身,并专注AB,那么你只能专注嵌套类模板,如果你还专门封装类.简而言之:只需通过额外的编译时间点间接来避免这些问题.