I am intending to declare a vector of atomic variables to be used as counters in a multithreaded programme. Here is what I tried:
#include
#in
As described in this closely related question that was mentioned in the comments, std::atomic isn't copy-constructible, nor copy-assignable.
Object types that don't have these properties cannot be used as elements of std::vector.
However, it should be possible to create a wrapper around the std::atomic element that is copy-constructible and copy-assignable. It will have to use the load() and store() member functions of std::atomic to provide construction and assignment (this is the idea described by the accepted answer to the question mentioned above):
#include
#include
template
struct atomwrapper
{
std::atomic _a;
atomwrapper()
:_a()
{}
atomwrapper(const std::atomic &a)
:_a(a.load())
{}
atomwrapper(const atomwrapper &other)
:_a(other._a.load())
{}
atomwrapper &operator=(const atomwrapper &other)
{
_a.store(other._a.load());
}
};
int main(void)
{
std::vector> v_a;
std::atomic a_i(1);
v_a.push_back(a_i);
return 0;
}
EDIT: As pointed out correctly by Bo Persson, the copy operation performed by the wrapper is not atomic. It enables you to copy atomic objects, but the copy itself isn't atomic. This means any concurrent access to the atomics must not make use of the copy operation. This implies that operations on the vector itself (e.g. adding or removing elements) must not be performed concurrently.
Example: If, say, one thread modifies the value stored in one of the atomics while another thread adds new elements to the vector, a vector reallocation may occur and the object the first thread modifies may be copied from one place in the vector to another. In that case there would be a data race between the element access performed by the first thread and the copy operation triggered by the second.