Сбой сравнения_обмена для std::shared_ptr в msvs 2013?

Посмотрите на образец, пожалуйста

std::atomic < std::shared_ptr < int > > a;

std::shared_ptr < int > b;
std::shared_ptr < int > c = std::make_shared < int > (10);

while(a.compare_exchange_weak(b, c));

assert(a.load() == c);  
assert(a.load().use_count() == 2); // <- assertion is failed.

Как вы думаете? Это ошибка компилятора?

Сборка с msvs 2013 в режиме win32

2 ответа

Решение

Ваша программа демонстрирует неопределенное поведение.

29.5 / 1 Существует универсальный шаблон класса atomic<T>, Тип аргумента шаблона T должно быть легко копируемым (3.9).

shared_ptr<int> не тривиально копируемый.

За ответ Игоря, std::atomic<std::shared_ptr<T>> не имеет определенного поведения. Вы должны использовать не-член shared_ptr перегрузка атомарных функций, как описано в C++11 §20.7.2.5 shared_ptr атомарный доступ [util.smartptr.shared.atomic].

std::shared_ptr < int > a;

std::shared_ptr < int > b;
std::shared_ptr < int > c = std::make_shared < int > (10);

while(std::atomic_compare_exchange_weak(&a, &b, c))
  ;

assert(std::atomic_load(&a) == c);  
assert(std::atomic_load(&a).use_count() == 2);

Мне кажется странным, что стандарт не требует частичной специализации template <typename T> struct std::atomic<shared_ptr<T>> быть реализованным с этими функциями.

Я не вижу упоминаний об элементарных перегрузках, не являющихся членами, в документации Microsoft <memory> заголовок, поэтому они не могут быть реализованы в VS2013.

Речь идет о C++11, но стоит отметить, что, начиная с C++20, код OP действителен, поскольку существует специализация дляstd::atomic для обоих shared_ptr а также unique_ptr.

Видеть: std::atomic<std::shared_ptr<T>> на cppreference

Кроме того, альтернатива использования std::atomic_compare_exchangeбыл устаревшим в C++20.

Другие вопросы по тегам