c-类范围内的类模板专业化?

为什么法律A中的专业S不是B中的S?

(如果B没有被注释掉)
GCC 4.8.1:错误:非命名空间范围“ 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;
}

on coliru: B commented out

on coliru: with B (error)

解决方法:

@jrok的注释几乎可以解释您的编译器错误.通常,嵌套类(尤其是嵌套类模板)是您可以轻松避免的该语言的尘土飞扬的角落(请注意萨特的建议“ Write what you know and know what you write”).

只需创建一个名称空间详细信息即可定义您的类模板SA和SB及其专业化,然后在A和B内定义嵌套的模板类型别名S

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

的确,在这种情况下,这似乎有些矫kill过正,但是,如果您想自己制作A和B类模板,并专门化A和B,那么,如果您还专门化封闭类,那么就只能专门化嵌套类模板.简而言之:通过额外的编译时间接级别完全避免这些问题.

上一篇:【前端】传统Coder了解前端Webpack技术的技术文章(转)


下一篇:不使用ASP.NET中的服务器控件将如何上传文件?