c ++将多个模板类类型限制为派生类

时间:2012-06-12 02:44:55

标签: c++ templates c++11

我关注template class restriction,但在gcc中遇到了错误:

错误:一个声明中有多种类型

错误:声明没有声明任何内容

如果我删除了enable_if块,它会编译。任何人都可以解释我是否遗漏了什么?

template<class A, class B, class C, class D>                                                                               
typename std::enable_if<                                                  
std::is_base_of<baseofA, A>::value &&                      
std::is_base_of<baseofB, B>::value &&      
std::is_base_of<baseofC, C>::value &&            
std::is_base_of<baseofD, D>::value>::type       
class library {
    //whatever
};

2 个答案:

答案 0 :(得分:3)

您没有正确使用enable_if。在这种情况下,static_assert会更合适。

template<class A, class B, class C, class D>       
class library {
  static_assert(
    std::is_base_of<baseofA, A>::value &&                      
    std::is_base_of<baseofB, B>::value &&      
    std::is_base_of<baseofC, C>::value &&            
    std::is_base_of<baseofD, D>::value, 
    "template argument A must derive from baseofA and so on ..." );
      //whatever
};

如果你想使用enable_if,你必须创建一个虚拟模板参数,该参数取决于启用的类型,以便它可以按你的意愿工作。

template<class A, 
         class B, 
         class C, 
         class D, 
         class _ = 
           typename std::enable_if<                                                  
             std::is_base_of<baseofA, A>::value &&                      
             std::is_base_of<baseofB, B>::value &&      
             std::is_base_of<baseofC, C>::value &&            
             std::is_base_of<baseofD, D>::value>
           ::type>
class library {
    //whatever
};

但IMO,static_assert方法更好,因为您可以提供描述性错误消息,而不是编译器抱怨在后一种情况下未能找到名为type的类型。

答案 1 :(得分:0)

点击this页后,尝试

template<class A, class B, class C, class D, class Enable = void>
class library;

template<class A, class B, class C, class D>                                                                      
class library<A, B, C, D, typename std::enable_if< std::is_base_of<baseofA, A>::value &&
                                                   std::is_base_of<baseofB, B>::value &&
                                                   std::is_base_of<baseofC, C>::value &&
                                                   std::is_base_of<baseofD, D>::value >::type
             >
{
    //whatever
};

请注意,您的示例一定有问题,因为enable_if&lt;&gt; :: type是一种类型,您不希望在模板&lt;&gt;之间使用它。行和类库行。