Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::atomic as a value of std::map

I want to use atomic variable in a map. I am using Visual Studio 2012 (msvc-11) and gcc 4.7. I have defined a type:

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

In msvc-11, lines

value_map_t map;
map[1] = 0;

produce error:

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

Same happens with gcc 4.7 (see here)

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

However, in Visual Studio 2013 (msvc-12) and beyond, as well as in gcc 4.8 and newer, it works fine.

See for yourself gcc 4.8 and Visual Studio 2013+

What can I do in msvc-11 / gcc 4.7 to make it work ?

like image 235
Vladimir Shutow Avatar asked Jan 29 '16 18:01

Vladimir Shutow


2 Answers

I don't have access to Visual C++ compilers, but I'm guessing the following might work. Use an indirection, utilizing a map to (smart) pointers of atomics:

#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;
}
like image 150
Ami Tavory Avatar answered Sep 28 '22 11:09

Ami Tavory


With a hint from @Yam Marcovic I found how to do it in 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;
}
like image 33
Vladimir Shutow Avatar answered Sep 28 '22 12:09

Vladimir Shutow