无法将“T&”类型的非常量左值引用绑定到 std::atomic<T> 类型的“T”t++ 右值

cannot bind non-const lvalue reference of type ‘T&’ to an rvalue of type ‘T’ t++ which std::atomic<T>

这是我的代码

#include <iostream>
#include <atomic>
using namespace std;

class T{
public:
    int i = 0;
    friend T operator++( T& t, int);
};

 T operator++( T& t, int){
        t.i++;
        return T(); // please ignore this. I only care for it to compile right now
    }



int main() {

    atomic<T> t;
    t++;
    return 0;
}

我正在尝试将原子与自定义 class B 结合使用,但我收到错误消息:

*Compilation error #stdin compilation error #stdout 0s 4400KB
prog.cpp: In function ‘int main()’:
prog.cpp:21:3: error: cannot bind non-const lvalue reference of type ‘T&’ to an rvalue of type ‘T’
  t++;
   ^~
In file included from prog.cpp:2:
/usr/include/c++/8/atomic:202:7: note:   after user-defined conversion: ‘std::atomic<_Tp>::operator _Tp() const [with _Tp = T]’
       operator _Tp() const noexcept
       ^~~~~~~~
prog.cpp:11:4: note:   initializing argument 1 of ‘T operator++(T&, int)’
  T operator++( T& t, int){
    ^~~~~~~~*

我正在使用 friend 来避免使用显式转换

(T(t))++;

如果我像这样用 const 定义 operator++:

friend T operator++(const T& t, int);

它可以编译,但当然对我没用。

当你做t++时,它和(t.operator T())++, which is equivalent to (t.load(std::memory_order_seq_cst))++一样。

这个returns原子持有的值的副本,它是一个右值。增加右值没有意义(它会立即被销毁),所以也许您想锁定、加载然后存储?

std::atomic<T>::operator++ 运算符仅为整数和指针定义(请参阅精美的绿色打印 here)。

编译器尝试调用 std::atomic<T>::operator T 来获取包含的 T 实例的临时副本,然后在其上调用您自己的 operator ++,因此需要 const 参考参数。 atomic 不提供锁定、调用您自己的操作员和解锁的方式。因为这可能会导致死锁(如果您的操作员获得了其他锁),这无论如何都会破坏 atomic 的目的。

您可能需要明确地使用像 std::mutex 这样的锁。