类范围中的类模板专门化? [英] Class template specialization in class scope?

查看:97
本文介绍了类范围中的类模板专门化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么S在A中的专业化是合法的,S在B中不是?

Why is the specialization S in A legal and S in B not?

(如果B没有注释掉)
GCC 4.8.1:error :非命名空间作用域中的显式专门化'B类'

( if B is not commented out ) GCC 4.8.1: error: explicit specialization in non-namespace scope ‘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;
}

on coliru:B commented out

在coliru上:与B(错误)

推荐答案

@jrok的注释很多解释你的编译器错误。一般的嵌套类,特别是嵌套类模板,是你可以很容易避免的一个尘土飞扬的角落(请注意Sutter的建议写你所知道的并知道你写的是什么)。

The comments by @jrok pretty much explains your compiler error. Nested classes in general, and nested class templates in particular, are a dusty corner of the language that you can easily avoid (taking to heart Sutter's advice "Write what you know and know what you write").

只需创建命名空间详细信息即可定义类模板 SA SB 及其特殊化,然后在中定义嵌套模板类型别名 S A B

Simply make a namespace detail to define your class templates SA and SB and their specializations and then define a nested template type alias S inside both A and 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 类模板本身,并专门 A B ,那么只能专门化嵌套类模板,如果你也专门化封装类。简而言之:只需通过额外的编译时间接方法避免这些问题。

Granted, for this case it might seem overkill, but if you ever want to make A and B class templates themselves, and specialize A and B, then you can only specialize the nested class templates if you also specialize the enclosing class. In short: just avoid these issues altogether by an extra level of compile-time indirection.

这篇关于类范围中的类模板专门化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆