How to declare a vector of atomic in C++

后端 未结 4 1870
暗喜
暗喜 2020-11-27 16:01

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         


        
4条回答
  •  悲哀的现实
    2020-11-27 16:40

    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.

提交回复
热议问题