C ++ 11 static_assert(以及其中使用的函数)

时间:2012-06-15 10:20:15

标签: c++ c++11 assertions static-assert

static_assert似乎是一个非常好的功能和模板。

但是,我无法在标准库中查找函数,以便在编译时进行各种测试。

例如,我正在寻找一个函数来检查类型是否是另一个类型的子类型。 boost::is_base_of这项工作确实是std中的一个类似函数,所以我不需要依赖boost。

基本上,有一个很好的函数列表可以在static_assert中使用并包含在C ++ 11的标准库中吗?

static_assert何时执行?我可以将它放在模板中的任何位置,并针对每个模板实例进行评估吗?它可以用来将模板参数约束为类的特定子类型吗?

2 个答案:

答案 0 :(得分:8)

查看最终的C++11 draft,第20.7节,尤其是<type_traits>标题。

您要问的是:std::is_base_of<base, derived>::value;

关于你的问题:只要编译器认为合适,就可以评估static_assert,但通常会:

  • 在模板中:如果表达式使用依赖名称,则在实例化时间内;否则,在定义时间。
  • 模板外:定义时间。

答案 1 :(得分:5)

除了@ rodrigo的回答(他更快......),

  

何时执行静态断言?我可以将它放在模板中的任何位置,并针对每个模板实例进行评估吗?它可以用来将模板参数约束为类的特定子类型吗?

不幸的是,没有。例如,无论模板如何,static_assert(false, "bummer"); 总是执行。如果您想(部分)专门化模板,这尤其会失败。

标准(§7.4)说:

  

[如果static_assert的条件是false],程序格式错误,生成的诊断消息(1.4)应包括字符串文字的文本,[...]

遗憾的是,这种情况非常不明确,但缺乏特异性实际上正是static_assert在不依赖于模板类型时的行为。

您需要使用static_assert中的条件取决于模板参数,以将其执行绑定到特定模板参数。

所以以下内容会失败:

template <typename T>
struct some_type {
    static_assert(false, "T must be a pointer type");
};

template <typename T>
struct some_type<T*> {
    // …
};

最后,我衷心建议您阅读Marthino关于More type traits的文章,其中详细介绍了这一过程,并提供了如何优雅地解决许多与特质相关的问题的提示。