Ссылка на удаленную функцию ошибка для std :: atomic <bool> - PullRequest
0 голосов
/ 08 апреля 2019

У меня есть std: atomic_bool, который я определил в своем коде следующим образом:

class A
{
public:
A();
A(const A&);
~A();

std::atomic_bool isTrue;
}

A:A()
{
isTrue= false;
}

A::A(const A&) : isTrue(false)
{}

Затем я делаю следующее:

class B
{
A aObj;

public:
bool getBool()
{
return GetNumberOfUsers() > 1 ? aObj.isTrue : true;
}

Я получаю следующую ошибку наgetBool() function.

Ошибка C2280 'std :: atomic :: atomic (const std :: atomic &)': попытка сослаться на удаленную функцию

IПонимаю, что это происходит потому, что конструктор копий атомик удаляется.Но я следовал этому ответу и определил конструктор копирования.Я в растерянности, почему ошибка все еще появляется.Я также попытался:

class A
    {
    ...  
    A(const A&) = delete;

Но все равно получил ошибку.

Редактировать : После устранения неполадок я столкнулся со странным поведением.Я обнаружил, что если я изменю свою троицу, если в B :: getBool (), как условно, следующим образом, я не получу ошибку.

bool getBool()
{
   // return GetNumberOfUsers() > 1 ? aObj.isTrue : true;
   if (GetNumberOfUsers() > 1)
        return aObj.isTrue ;
   else
        return true;
}

Теперь это еще более запутанно.

РЕДАКТИРОВАТЬ 2:

После небольшого устранения неполадок я обнаружил, что проблема, вероятно, тип возврата.в троичном, если условное exp1 ? exp2 : exp3, тип возвращаемого значения - это тип exp2 (как объяснено здесь ).Так что в этом случае тип возвращаемого значения B :: getBool () становится atomic_bool, а не atomic.Когда я добавил static_cast код к следующему, я больше не получаю ошибку.

bool getBool()
{
        return GetNumberOfUsers() > 1 ? static_cast<bool>(aObj.isTrue) : true;
}

Однако я все еще не знаю, почему это вызовет ошибку конструктора копирования.Спасибо.

1 Ответ

1 голос
/ 08 апреля 2019

Вы условное выражение

GetNumberOfUsers() > 1 ? aObj.isTrue : true;

не должен компилироваться. Однако причина этого не имеет ничего общего с конструктором копирования std::atomic<bool>. Два выражения, между которыми это условное переключение: во-первых, lvalue типа класса std::atomic<bool> и, во-вторых, prvalue не типа класса bool. Существует неявная последовательность преобразования из bool в std::atomic<bool>. Также существует неявная последовательность преобразования из std::atomic<bool> в bool. Исходя из [expr.cond] / 4 , эта программа, следовательно, должна быть плохо сформирована.

Я считаю, что тот факт, что MSVC, по-видимому, пытается сделать это выражение результатом std::atomic<bool>, должен быть ошибкой в ​​MSVC. Обратите внимание, что текущие версии MSVC при переключении в режим соответствия (через опцию /permissive-; все должны использовать это, если могут), правильно диагностируют проблему в соответствии с другими компиляторами. живое демо здесь

Как вы уже узнали, использование aObj.load() для получения значения bool, явное преобразование aObj.isTrue в bool или замена условного выражения на оператор if решит проблему ...

...