【问题标题】:Rationale for type traits checking triviality of class special functions类型特征检查类特殊函数的琐碎性的基本原理
【发布时间】:2017-02-20 20:29:02
【问题描述】:

除了std::is_trivialstd::is_trivially_copyable 之外,C++11 还提供了许多类型特征来检查类型是否具有普通的构造函数、析构函数和复制/移动赋值运算符,即:

  • std::is_trivially_constructible
  • std::is_trivially_default_constructible
  • std::is_trivially_copy_constructible
  • std::is_trivially_move_constructible
  • std::is_trivially_assignable
  • std::is_trivially_copy_assignable
  • std::is_trivially_move_assignable
  • std::is_trivially_destructible

他们最初的预期目的是什么?当然,一些 C++ 委员会论文必须解释将它们包含在 C++ 标准库中的理由。

【问题讨论】:

  • 它们非常适合在单元测试中查看是否有人搞砸了并做出了一些必须琐碎的事情_无论什么不是琐碎的,导致在生产代码中无声地调用未定义的行为。还要在生产代码中制作漂亮的static_assert 编译时陷阱,以防有人真的愚蠢而不是单元测试。

标签: c++ c++11 c++14 language-lawyer c++17


【解决方案1】:

为什么它们在标准库中?因为它们很有用,但无法在该语言中实现。


有用的两个具体例子。

  • std::is_trivially_copy_constructible - 如果我有一个可以简单复制构造的vector,我不需要在重新分配时单独复制每个元素。我可以一口气memcpy() 整个街区。我们需要这种类型特征来检查这种优化何时是安全的。
  • std::is_trivially_destructible - Trivial destruction 是一个类型的重要品质。它是文字类型的标准之一,因此可用于常量表达式。在某些情况下,我可能希望我的类型可用作文字类型,而这种情况可能会发生(例如std::optional)。我们需要这种类型特征来使optional<T> 有条件地可简单地破坏。

【讨论】:

  • “如果我有一个可以简单复制构造的向量,我不需要在重新分配时单独复制每个元素。”这需要微不足道的可复制性。
  • 我已经读到 memcpy 可能比使用普通的复制构造函数效率低得多,因为编译器生成的指令复制整个大块内存,而 memcpy 逐字节复制......所以好消息只是不关心类型的这个属性,如果你不使用它,(现代)编译器会做得更好。
  • @Oliv 为什么你认为编译器可以生成高效的代码来复制一堆对象,而不是一堆字节?
  • @Barry 因为一个类型的值表​​示并不总是匹配那个类型的对象表示 (basic.types/4)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 2016-02-05
  • 2019-12-04
相关资源
最近更新 更多