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
To first answer your headline question: you can declare a std::vector easily, as you have done in your example.
Because of the lack of copy or move constructors for std::atomic<> objects, however, your use of the vector will be restricted as you found out with the compilation error on push_back(). Basically you can't do anything that would invoke either constructor.
This means your vector's size must be fixed at construction, and you should manipulate elements using operator[] or .at(). For your example code, the following works1:
std::vector> v_a(1);
std::atomic a_i(1);
v_a[0] = a_i;
If the "fixed size at construction" limitation is too onerous, you can use std::deque instead. This lets you emplace objects, growing the structure dynamically without requiring copy or move constructors, e.g.:
std::deque> d;
d.emplace_back(1);
d.emplace_back(2);
d.pop_back();
There are still some limitations, however. For example, you can pop_back(), but you cannot use the more general erase(). The limitations make sense: an erase() in the middle of the blocks of contiguous storage used by std::deque in general requires the movement of elements, hence requires copy/move constructor or assignment operators to be present.
If you can't live with those limitations, you could create a wrapper class as suggested in other answers but be aware of the underlying implementation: it makes little sense to move a std::atomic<> object once it is being used: it would break any threads concurrently accessing the objects. The only sane use of copy/move constructors is generally in the initial setup of collections of these objects before they are published to other threads.
1 Unless, perhaps, you use Intel's icc compiler, which fails with an internal error while compiling this code.