【问题标题】:Why does std::atomic<T>::operator= should return a value instead of reference?为什么 std::atomic<T>::operator= 应该返回一个值而不是引用?
【发布时间】:2021-03-06 07:39:45
【问题描述】:

在 c++ 中使用原子类型时

为什么 std::atomic::operator= 应该返回一个值而不是引用? 它不像其他常见的返回引用的赋值运算符。

cppreference 网站我可以得到一些提示。

与大多数赋值运算符不同,原子类型的赋值运算符不返回对其左侧参数的引用。它们会返回存储值的副本。

我可以猜到,如果我使用引用,它就会有原子事物的问题。 但我并不完全清楚。

你有异步错误案例的例子吗?

如果我返回一个值而不是一个引用,为什么异步错误消失了?

【问题讨论】:

  • 它返回一个T,而不是atomic&lt;T&gt;。如果它返回对非原子类型的引用,那么这一切都没有意义。

标签: c++ concurrency atomic


【解决方案1】:

你有异步错误案例的例子吗?

该运算符的返回类型是T。如果是T&amp;,你可以这样做:

atomic<int> i;
++(i = 10);

++ 将是非原子读-增量-写,这是非常错误的。

如果我返回一个值而不是一个引用,为什么异步错误消失了?

因为它返回一个副本,而不是一个引用,所以你不能做我上面展示的事情。

【讨论】:

  • 但 atomic 支持 ++ 操作。如果return atomic&,是否可以增加?
  • 如果它返回atomic&lt;int&gt;&amp;,那是可能的。
  • 那么原子类型 operator= 不返回 atomic& 的原因是什么?
  • @myoldgrandpa 可能是因为这样很难将分配与其他内容联系起来,例如另一个分配或if 或其他类型。
【解决方案2】:

operator= 有一个返回值,允许在一行中进行多个赋值:

Object a, b;
// Short form
a = b = <value>;
// Equivalent long form
a = <value>;
b = <value>;

为了完成这个行为,可以考虑std::atomic&lt;T&gt;::operator=返回TT &amp;std::atomic&lt;T&gt; &amp;

  • T

    这就是操作符的实际实现方式。

  • T &amp;

    像指针一样,引用应该指向到 T 类型的 object。 但是没有 T 对象存储在原子对象中!

    所以,没有什么适合返回为T &amp;

  • std::atomic&lt;T&gt; &amp;

    对于这样的返回类型,一个不能

    std::atomic<uint32_t> a, b;
    a = b = 5;
    

    b = 5 返回类型std::atomic&lt;T&gt; &amp;,一个不能赋值 该类型的原子变量 a 因为对应于 operator= 被标记为 deleted(禁止将一个原子变量分配给另一个)。

正如我们所见,允许多个分配的唯一可能方法是返回T,因为它实际上已实现。

【讨论】:

  • 像指针一样,引用应该指向 T 类型的对象。但是原子对象中没有存储 T 对象! => 你是什么意思?原子类型有它的价值
  • 原子类型表现就像它有一个 T 值一样。原子实现甚至可以有这个值,但它显然不会直接访问它。
猜你喜欢
  • 2016-11-10
  • 2012-10-25
  • 2011-07-03
  • 1970-01-01
  • 2020-07-17
  • 2017-04-07
  • 2020-03-08
  • 2015-09-30
  • 1970-01-01
相关资源
最近更新 更多