【问题标题】:Is std::atomic<std::optional<std::chrono::time_point<std::chrono::system_clock>>> valid/safe?std::atomic<std::optional<std::chrono::time_point<std::chrono::system_clock>>> 是否有效/安全?
【发布时间】:2021-02-14 21:33:03
【问题描述】:

根据Does std::atomic<std::string> work appropriately?std::atomic&lt;std::string&gt; 无效,可能导致未定义的行为。

std::atomic&lt;std::optional&lt;std::chrono::time_point&lt;std::chrono::system_clock&gt;&gt;&gt; 呢?

std::optionaloperator=std::chrono::time_point 没有,所以我很困惑。我如何确定任何类型?

【问题讨论】:

  • AFAIK std::optional 仅当其持有的类型可轻松复制且 time_point 可轻松复制时才可轻松复制。

标签: c++ c++11


【解决方案1】:

如链接线程中所述,std::atomic&lt;T&gt; 要求 T 可以轻松复制。

这里的Tstd::optional&lt;U&gt; 一些Ustd::optional 类模板转发琐碎:它的复制构造函数、移动构造函数、复制赋值运算符、移动赋值运算符和析构函数如果对于 U 来说都是微不足道的,那么它们都是微不足道的。

没有铁定的保证std::chrono::time_point&lt;std::chrono::system_clock&gt; 可以轻松复制。 time_point 的底层表示可能是算术类型或“模拟算术类型的类”([time.duration]/2),我认为它足够灵活,允许例如非平凡复制构造函数(即使它们与普通的复制构造函数具有相同的语义)。如果是这种情况,time_point 将无法轻易复制。

无论如何,std::atomic&lt;std::optional&lt;std::chrono::time_point&lt;std::chrono::system_clock&gt;&gt;&gt; 可以安全使用如果它编译。如果std::atomic&lt;T&gt; 中的T 不可轻易复制,编译器必须发出诊断,因为如果不满足此条件([atomics.types.generic]/1),标准会说“程序格式错误”。在该标准的早期版本中,措辞是“......应该可以轻松复制”,这也是一个可诊断的规则,因为它没有说“否则行为未定义”或类似的内容。

【讨论】:

    【解决方案2】:

    检查很简单:

    static_assert(std::is_trivially_copyable_v<
        std::optional<std::chrono::time_point<std::chrono::system_clock>>>);
    

    在 gcc 8.1(和相关的 libstdc++)之前,断言失败,因此使用起来不安全。在 gcc 8.1 之后,断言通过了,所以它是安全的。

    在 clang 7(以及相关的 libc++)之前,断言失败,因此使用起来不安全。在 clang 7 之后,断言通过并且它是安全的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 2015-06-04
      • 2017-09-02
      • 2020-10-13
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      相关资源
      最近更新 更多