не может связать неконстантную ссылку lvalue типа 'T &' с rvalue типа 'T' t ++, который std :: atomi c<T> - PullRequest
0 голосов
/ 15 января 2020

это мой код

#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;
}

Я пытаюсь использовать atomi c с пользовательским классом 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){
    ^~~~~~~~*

Я использую друг чтобы не использовать явное преобразование

(T(t))++;

, если я определяю оператор ++ с помощью const, например:

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

он компилируется, но, конечно, его бесполезно для меня.

Ответы [ 2 ]

3 голосов
/ 15 января 2020

Когда вы делаете t++, это то же самое, что и (t.operator T())++, что эквивалентно (t.load(std::memory_order_seq_cst))++.

Возвращает копию значение, удерживаемое атомом c, которое является значением. Увеличение значения r не имеет смысла (оно немедленно уничтожается), поэтому, возможно, вы хотите заблокировать, загрузить и затем сохранить?

1 голос
/ 15 января 2020

Операторы std::atomic<T>::operator++ определены только для целых чисел и указателей (см. Мелкий зеленый шрифт здесь ).

Компилятор пытается вызвать std::atomic<T>::operator T для получения временной копии содержащийся экземпляр T, а затем вызовите свой собственный operator ++, для чего требуется ссылочный параметр const. atomic не позволяет блокировать, вызывать собственного оператора и разблокировать. Поскольку это может привести к взаимоблокировкам (если ваш оператор получит какую-то другую блокировку), это в любом случае подорвет цель atomic.

Возможно, вам придется использовать блокировку, например std::mutex явно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...