【问题标题】:C++11 static_assert (and functions to be used therein)C++11 static_assert(以及其中使用的函数)
【发布时间】:2012-06-15 10:20:14
【问题描述】:

static_assert 与模板一起似乎是一个非常不错的功能。

但是,我很难在标准库中找到用于在编译时进行各种测试的函数。

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

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

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

【问题讨论】:

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


【解决方案1】:

看看最后的 C++11 draft,第 20.7 节,特别是 <type_traits> 标头。

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

关于您的问题:static_assert 可以在编译器认为合适时进行评估,但通常会:

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

【讨论】:

  • 完美,谢谢!这正是我想要的。我可以用它来约束模板的类型参数吗?
  • @gexicide - 是的,这实际上就是 的原因。
  • n3092 实际上是在终稿前一年左右。 n3290 是标准完成之前的最新可用草案。您可能应该使用 n3337,它是在标准化之后立即发布的,与官方标准的唯一区别是更正了拼写错误等。
  • 你可以得到n3337here (5MB pdf)。有更多的更新,甚至是对工作文件更高版本的错误修复进行了投票,一些编译器甚至实现了它们,但这是自 n3290 被取消以来免费提供的最接近官方标准的文档。
  • 哦,如果有人关心标准的实际 TeX 源代码现在在 GitHub 上,请关心当前编辑:github.com/cplusplus/draft
【解决方案2】:

除了@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 上的文章,该文章更详细地介绍了这个过程,并给出了如何优雅地解决许多与 trait 相关的问题的提示。

【讨论】:

  • template &lt;typename T&gt; struct X { static_assert(std::is_base_of&lt;Y,T&gt;::value,"T must be derived from Y!");怎么样
  • @gexicide 这显然有效,因为条件现在取决于 YT 的类型,并且它无法在他们不知情的情况下解决)。
  • 太好了,正是我想要的:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多