2016-01-29 3 views
2

Я хочу использовать атомную переменную на карте. Я использую Visual Studio 2012 (msvc-11) и gcc 4.7. Я определил тип:std :: atomic как значение std :: map

typedef std::map<uint64_t, std::atomic<int64_t>> value_map_t; 

В MSVC-11, линии

value_map_t map; 
map[1] = 0; 

ошибка продукции:

error C2248: std::atomic<__int64>::atomic : cannot access private member declared in class std::atomic<__int64>

То же самое происходит с GCC 4.7 (see here)

error: use of deleted function std::atomic<long int>::atomic(const std::atomic<long int>&)

Однако, в Visual Studio 2013 (msvc-12) и выше, а также в gcc 4.8 и новее, он работает нормально.

Смотрите сами gcc 4.8 и Visual Studio 2013+

Что я могу сделать в MSVC-11/GCC 4.7, чтобы сделать его работу?

+2

'станд: : atomic' - это функция C++ 11, вы, вероятно, не должны ожидать, что эти вещи будут работать очень хорошо, если вы не захотите использовать компилятор, предлагающий надежную поддержку для C++ 11. Оба gcc 4.7 и msvc-11 были довольно пятнистыми в этом отношении. –

ответ

2

У меня нет доступа к компиляторам Visual C++, но я предполагаю, что следующее может работать. Используйте окольные, используя карту (смарт) указатели atomic с:

#include <atomic> 
#include <map> 
#include <memory> 


using atomic_ptr_t = std::shared_ptr<std::atomic<int64_t>>; 
typedef std::map<uint64_t, atomic_ptr_t> value_map_t; 


int main() 
{ 
    value_map_t map; 
    map[1] = atomic_ptr_t(new std::atomic<int64_t>(0)); 

    return 0; 
} 
+0

Это действительно работает. Было бы неплохо, однако, избегать дополнительных новых() для каждой вставки для эффективности, а также для .get() для извлечения. Интересно, как вокруг него работают новые компиляторы? –

+0

@VladimirShutow Я полностью согласен с вами. Опять же, у меня нет доступа к этому компилятору. Сожалею. –

+0

В случае, если вы хотите протестировать его, есть онлайн-компилятор gcc 4.7.3, я упомянул в вопросе http://melpon.org/wandbox/permlink/J3cJEjnIygLWnkhl , но спасибо за это решение. –

1

С намеком от @Yam Marcovic я нашел, как это сделать в Visual Studio 2012:

#include <atomic> 
#include <map> 
#include <tuple> 

typedef std::atomic<int64_t> value_t; 
typedef std::map<uint64_t, value_t> atomic_map_t; 

int main() 
{ 
    int64_t in = 5; 

    atomic_map_t map; 
    map.emplace(std::piecewise_construct, 
      std::forward_as_tuple(1), std::forward_as_tuple(in)); 

    auto it = map.find(1); 
    int64_t out = it->second.load(); 

    return 0; 
}