编译时间模板限制C ++

时间:2015-05-15 14:39:53

标签: c++ templates inheritance polymorphism

基本上我有4个班级:

  • OverVoid
  • Meta:继承OverVoid
  • 物理:与上述
  • 无关
  • 移动:模板类

我希望移动模板接受只有OverVoid类型的对象,即Ove​​rVoid和Meta。

class OverVoid{
public:

    virtual ~OverVoid(){
    };
};

class Meta: public OverVoid{

};

class Physical{
public:
};

template<typename _Ty>
class Move{

};

我希望在编译时输入错误, 我知道有一种方法可以提升,但我不能使用Boost(我公司的开发问题)

任何想法?

3 个答案:

答案 0 :(得分:5)

最简单的事情就是static_assert

template<typename _Ty>
class Move {
    static_assert(std::is_base_of<OverVoid, _Ty>::value, 
                  "_Ty must inherit from OverVoid.");
};

请注意,这允许OverVoid成为私有或无法访问的基础。如果您想要求它是公共基础,您可以要求:

    static_assert(std::is_convertible<_Ty*, OverVoid*>::value, 
                  "_Ty must inherit publicly from OverVoid.");

答案 1 :(得分:1)

您可以隐藏不属于OverVoid

类的类的模板定义
template<typename _Ty, 
         class = typename std::enable_if<std::is_base_of<OverVoid, _Ty>::value>::type>
class Move{

};

在尝试编译非OverVoid类的类时,您会收到错误。

int main() {

  Move<Meta> a;
  Move<OverVoid> b;
  Move<Physical> c;
  // your code goes here
  return 0;
}

错误:

prog.cpp: In function 'int main()':
prog.cpp:29:15: error: no type named 'type' in 'struct std::enable_if<false,    void>'
Move<Physical> c;

答案 2 :(得分:1)

使用std::enable_if

template <typename T>
struct is_overvoid_or_meta
{
     static const bool value = false;
};

template <> struct is_overvoid_or_meta<OverVoid>
{
     static const bool value = true;
};

template <> struct is_overvoid_or_meta<Meta>
{
     static const bool value = true;
};

//Add specialization for all valid types - this allows you to more precisely tell, what types can be used as a template argument for Move

然后:

template<typename _Ty>
class Move
{
     typedef std::enable_if<is_overvoid_or_meta<_Ty>::value, _Ty>::type Type;
};

每种类型都会出现编译时错误,不是OverVoidMeta(或者更常见的是,对于每个Tis_overvoid_or_meta<T>::valuefalse is_overvoid_or_meta - 如果您将来添加更多内容,可能需要将is_acceptable_by_move更加一般化,例如int main() { Move<OverVoid> m1; Move<Meta> m2; Move<int> m3; return 0; } 或其他内容:

Move

输出:

  

错误:'struct std :: enable_if'

中没有名为'type'的类型      

typedef typename std :: enable_if :: value,_Ty&gt; :: type Type;

Live sample

这是一个非常好的解决方案,因为它不会被欺骗 - OverVoid的其他模板参数总是可以手动指定(除非Meta@products = Product.where(:discount => 0, :nonproduct => 0) @products = @products.where('products.number like ?', query) 不向客户端公开)。< / p>