Недавно я перешел на компилятор, совместимый с C ++ 11, и пытался обновить код с буста до стандартов c ++ 11. Я столкнулся с проблемой при преобразовании некоторого кода с использованием atomic_store. Вот некоторый простой тестовый код, который, кажется, выдает ошибку компилятора для меня.
int main()
{
std::shared_ptr<int> m = std::make_shared<int>();
*m = 1;
std::shared_ptr<int> a = std::make_shared<int>();
*a = 2;
std::atomic_store(&m,std::move(a));
std::cout << *m << std::endl;
}
std::atomic_store(&m,std::move(a));
строка выдает ошибку компилятора для меня:
'std::shared_ptr<int>' is not derived from 'volatile std::atomic<_ITp>'
std::atomic_store(&m,std::move(a));
^
Изменился ли способ atomic_store при переходе с boost на C ++ 11? Теперь мне нужно создать атомарный объект общего указателя?
Следующий код прекрасно компилируется с Clang 3.5:
#include <memory>
int main()
{
std::shared_ptr<int> foo, bar;
std::atomic_store(&foo, bar);
}
Тем не менее, он не компилируется с GCC 4.9. Приведенный выше код выводит сообщение об ошибке, которое atomic_store
не является членом std
, Если я также включу <atomic>
, компилятор печатает сообщение об ошибке, показанное в вопросе.
По-видимому, GCC 4.9 не поддерживает атомарные операции для std::shared_ptr
, Смотрите также документацию libstdc ++:
20.7.2.5 | shared_ptr атомарный доступ | частичный
В настоящее время единственный безопасный и надежный способ предотвратить состояние гонки (когда
интеллектуальный указатель, копируемый в один поток, одновременно сбрасывается в
другое) всегда использовать мьютексы при доступе к этим объектам, но это
дороже, чем нужно, особенно если несколько читателей
пытается прочитать данные примерно в один и тот же момент (что типично для
модель издателя / подписчика).