I am exploring the use of std::atomic in a struct across translation units and have run into a constructor compile problem. When I try to use explicit instantiation, the compiler says they don't match. How do I match up the explicit instantiation and the A constructor?
#include <string>
#include <atomic>
#include <map>
struct A
{
A( std::string strArg, bool onOffArg ) // added constuctor after compiler complained it couldn't find one that matched
: str { strArg }, onOff { onOffArg } {}
~A() {}
std::string str {};
std::atomic< bool > onOff { false }; // (see Edit1, Remy Lebeau). error C2440: 'initializing': cannot convert from 'initializer list' to 'std::map<int,A,std::less<int>,std::allocator<std::pair<const int,A>>>', 'No constructor could take the source type, or constructor overload resolution was ambiguous'
};
A( const A& oldA ) // (see Edit2, Eugene)
{
str = oldA.str;
onOff.store( oldA.onOff.load() );
}
int main()
{
std::map< int, A > aMap
{
{ 1, { "One", false } } // assuming inner braces are a match for A ctor
};
}
Edit1: Fixed atomic constructor.
Edit2:
Copy ctor was missing (see reply to Eugene comment). Also, atomic
's store
and load
need to be used instead of assign in copy ctor.
The immediate problem is that struct A
is non-copyable and non-movable: its auto-generated copy and move ctors are deleted because std::atomic
is non-copyable and non-movable. A map with a non-movable value type can be created, but many operations on it are disabled, including the construction from the initializer list.
The underlying design problem is your decision to use std::atomic
flag as part of a struct. In a multi-threaded environment, you probably want to synchronize updates to all struct members. In this case, it is better to include a non-atomic flag in the struct, and protect the operations modifying the map with a mutex.
So, your struct could be just
struct A
{
std::string str;
bool onOff;
};
and you make a wrapper class containing both std::map< int, A >
and a mutex, with non-const methods containing locks on the mutex.