VS2017 provides the following error when I try to add a std::atomic
to a struct stored in an std::pair
(inside an std::unordered_map
):
error C2660: 'std::pair<uint32_t,AtomicStruct>::pair': function does not take 2 arguments
I've simplified the issue down to the following code (removing the std::unordered_map for clarity/focus):
#include <iostream> // std::cout#include <utility> // std::pair#include <atomic> // std::atomicstruct AtomicStruct{ std::atomic_uint32_t a; // associated data goes here...};using AtomicPair = std::pair<uint32_t, AtomicStruct>;int main(){ AtomicStruct as = { 1 }; // This initializer works just fine std::cout << "as: "<< as.a << std::endl; // Outputs "as: 1" as expected AtomicPair pr1(0, as); // error C2660 AtomicPair pr2(0, { 1 }); // error C2660 return 0;}
From what I've pieced together so far:
std::atomic
deletes the copy-constructor.std::pair
's template checks for the parameters beingis_copy_constructible
, when the parameters specify thefirst
andsecond
of the std::pair.- Because the
std::atomic
, or second, parameter isn'tis_copy_constructible
, the constructor definition isn't created. - The compiler then falls back to the
std::pair(const std::pair&) = default
copy constructor, which fails because the number of parameters is incorrect (two, instead of one), as well as the type is wrong.
If I remove the std::atomic
from the struct, I can put it directly into a std::pair
std::pair<uint32_t, std::atomic_uint32_t> pr3(0, 1); // Works!
I thought maybe the initializer was being used for construction too early, and also tried:
AtomicPair pr4(0, { { 1 } }); // error C2660
Maybe I'm missing something obvious... Does anyone know a way to store structs containing std::atomic
s in a std::pair
?