【问题标题】:Compiler Error C2766 : "explicit specialization; 'specialization' has already been defined" when using boost::disable_if编译器错误 C2766:使用 boost::disable_if 时“显式特化;‘特化’已被定义”
【发布时间】:2012-01-19 10:17:04
【问题描述】:

我正在尝试构建一个模板类Fod

template<typename S0 = aux::EmptyType, typename S1 = aux::EmptyType, typename S2 = aux::EmptyType, typename S3 = aux::EmptyType, typename S4 = aux::EmptyType, typename S5 = aux::EmptyType, typename S6 = aux::EmptyType, typename S7 = aux::EmptyType, typename S8 = aux::EmptyType, typename S9 = aux::EmptyType>
class Fod { ... };

其中将包含一个内部类 At 和一个 static const int value 指示模板参数的索引(0 表示 S0,1 表示 S1 等等)。很快,它应该满足条件:

struct Type0 {}; struct Type1 {};
BOOST_STATIC_ASSERT( (Fod<Type0>::At<Type0>::value == 0) );
BOOST_STATIC_ASSERT( (Fod<Type0, Type1>::At<Type0>::value == 0) );
BOOST_STATIC_ASSERT( (Fod<Type0, Type1>::At<Type1>::value == 1) );

我尝试使用boost::disable_if,如下所示:

template<class T, class Enable = void>
class At; // undefined

template<>
struct At<S0, typename boost::disable_if<boost::is_same<S0, aux::EmptyType> >::type > {
    static const int value = 0;
};

template<>
struct At<S1, typename boost::disable_if<boost::is_same<S1, aux::EmptyType> >::type > {
    static const int value = 1;
};

template<>
struct At<S2, typename boost::disable_if<boost::is_same<S2, aux::EmptyType> >::type > {
    static const int value = 2;
};

template<>
struct At<S3, typename boost::disable_if<boost::is_same<S3, aux::EmptyType> >::type > {
    static const int value = 3;
};

// and so on for S4...S9

但是当我为 S3 定义特化并且 S2、S3 都属于同一类型 aux::EmptyType 时会导致错误(或者:我为 S2 定义特化并且 S1、S2 都属于同一类型)。

4>C:\phd\cpp\src\boost/dst/fod.hpp(144): error C2766: explicit specialization ; 'boost::dst::fod<S0>::At<boost::dst::aux::EmptyType,boost::mpl::s_item<T,Base>>' has already been defined
4>          with
4>          [
4>              S0=Type0
4>          ]
4>          and
4>          [
4>              T=Type0,
4>              Base=boost::mpl::set0<>::item_
4>          ]

任何想法如何解决这个问题? 如果我想要一个方法 size_t at&lt;S0&gt;() 给 0,size_t at&lt;S1&gt;() 给 1...?

如果您需要更多信息,请询问。

【问题讨论】:

  • 如果您的编译器对 C++11 的支持足够好,您可以使用 variadic templates?,而不是声明所有这些模板参数
  • 实际上,我不能使用 C++11,因为还有其他人会使用该代码,它应该可以在 C++03 中使用。
  • 似乎是一个复杂的代码

标签: c++ boost compiler-errors template-specialization enable-if


【解决方案1】:

对此有一个更简单的解决方案,假设 boost::is_same::value 返回 0 或 1(如果您的 bool 使用不同的值,只需编写一个小的编译时转换器): 将您当前的 At 替换为

template <typename T>
struct At {
    enum {
        value = 
        boost::is_same<T, S0>::value) + 
        boost::is_same<T, S1>::value * 10 + 
        boost::is_same<T, S2>::value * 100
    };
};

计算为十进制位掩码,如果您需要更大的范围,请随意使用其他值。

【讨论】:

    【解决方案2】:

    感谢this answer,我已经成功回答了第二个问题(关于模板函数):

    #include <boost/utility/enable_if.hpp>
    
    template <typename T>
    static int at(typename boost::enable_if_c< boost::is_same<T, S0>::value && !boost::is_same<T, aux::EmptyType>::value, T >::type = T())
    {
        return 0;
    }
    // and so on for each class template parameter S1,...,S9
    

    【讨论】:

      【解决方案3】:

      我也回答了我的第一个问题。实际上,我认为这更容易:

      // main general template (unused or throws a compilation error)
      template<class T, class Enable = void >
      struct At {};
      
      template<typename T>
      struct At<T, typename boost::enable_if< boost::is_same<T, S0> >::type >
      {
          static const int value = 0;
      };
      // and so on for each class template parameter S1,...,S9
      

      【讨论】:

        猜你喜欢
        • 2019-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多