c++ - std::atomic::operator++ 真的按值返回吗?

标签 c++ c++11 operator-overloading atomic c++-standard-library

根据this前缀 std::atomic<T>::operator++返回 T ,所以这段代码只会增加 v一次:

template<class T> void addTwo(std::atomic<T>& v) {
  ++(++v);
}

另外,std::atomic<T>::operator= apparently返回 T ,因此此代码取消引用一个无效指针,该指针曾经指向临时 T :

template<class T>
void setOneThenTwo(std::atomic<T>& v) {
  auto ptr = &(v = 1);
  *ptr = 2;
}

我绝对不是说这些代码模式是好的实践,但是让我非常惊讶的是 std::atomic打破他们。我一直期待 operator=和前缀 operator++返回对 *this 的引用.

问题: cppreference 关于此处的返回类型是否正确,如果正确,是否有充分的理由使用 std::atomic在这方面的行为与内置类型不同?

最佳答案

如果 operator++返回一个引用,它将是对 std::atomic<T> 的引用不去T在这种情况下,您需要做一个额外的 load获取当前值。

假设您有一个 DBMS,并且需要维护一个“自动增量”字段

operator++重调T你可以这样做

class AutoIncrement
{
public:
   AutoIncrement() : current (0) {}

   unsigned int next()
   {
      return ++current;
   }

private:
   std::atomic<unsigned int> current;
};

现在想象一下 operator++返回 std::atomic<T>& 在那种情况下,当您执行 return ++current它会做两件事

  1. 原子读-修改-写
  2. 原子负载

它们是两个完全独立的操作。如果其他线程调用next在这两者之间,您的自动增量字段会得到错误的值!

关于c++ - std::atomic::operator++ 真的按值返回吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13231048/

相关文章:

c++ - 为什么 MinGW 会自动包含 <windef.h>

c++ - double /整数使用和基于范围的 for 循环中的数据缩小

c++ - 继承类中对运算符 << 的 undefined reference

c++ - 为什么包含 std::stringstream 的类的 move 语义会导致编译器错误?

c - 测量任何编程语言的程序的时间复杂度

C++ 运算符重载返回指针

java - Jexl3 中自定义类的运算符重载/定义

c++ - 当通过成员函数将文字传递给构造函数时,为什么没有将值分配给类的成员?

c++ - 如何在C++中将字符转换为字符串?

c++ - 类似 STL 对的三元组类 - 我自己滚动吗?