I am trying to create a structure and insert that a map as following:
struct Queue_ctx {
std::mutex qu_mutex;
std::condition_variable qu_cv;
std::queue<std::vector<std::byte>> qu;
};
std::map<std::string, Queue_ctx> incoming_q_map;
Queue_ctx qctx;
std::vector<std::byte> vect(100);
qctx.qu.push(vect);
incoming_q_map.emplace("actor", qctx);
But I get the following error :
error C2660: 'std::pair<const std::string,main::Queue_ctx>::pair': function does not take 2 arguments
message : see declaration of 'std::pair<const std::string,main::Queue_ctx>::pair'
message : see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const char(&)[6],main::Queue_ctx&>(_Alloc &,_Objty *const ,const char (&)[6],main::Queue_ctx &)' being compiled
with
[
_Alloc=std::allocator<std::_Tree_node<std::pair<const std::string,main::Queue_ctx>,std::_Default_allocator_traits<std::allocator<std::pair<const std::string,main::Queue_ctx>>>::void_pointer>>,
_Ty=std::pair<const std::string,main::Queue_ctx>,
_Objty=std::pair<const std::string,main::Queue_ctx>
]
AFAIU, emplace constructs the element inplace. if that is true then why compiler is trying to create pair to emplace? I see that the syntax of pair synthesized by the compiler is odd that's why it complains. But why does that happen and what can I do to fix this problem ?
I tried to pass make_pair()
explicitly but that did not help.
If I comment the qu_mutex
and qu_cv
then I am able to do emplace. What does error has to do with these two members? Isn't the case that default consutructor initializing the members of struct ?
I know copy/assignment/move constructors are deleted by the compiler.
CodePudding user response:
Anyway to fix this problem you need customize copy constructor and assignment operator.
Also mutex suggest some synchronization of qu
in all scenerios, so all fields should be private (so struct
should be changed to class
).
class Queue_ctx {
mutable std::mutex qu_mutex;
std::condition_variable qu_cv;
std::queue<std::vector<std::byte>> qu;
public:
Queue_ctx() = default;
Queue_ctx(const Queue_ctx& other)
: Queue_ctx(other, std::scoped_lock{ other.qu_mutex })
{
}
Queue_ctx(const Queue_ctx& other, const std::scoped_lock<std::mutex>&)
: qu { other.qu }
{
}
Queue_ctx(Queue_ctx&& other)
: Queue_ctx(std::move(other), std::scoped_lock{ other.qu_mutex })
{
}
Queue_ctx(Queue_ctx&& other, const std::scoped_lock<std::mutex>&)
: qu { std::move(other.qu) }
{
}
Queue_ctx& operator=(const Queue_ctx& other)
{
std::scoped_lock lock{ qu_mutex, other.qu_mutex };
qu = other.qu;
return *this;
}
Queue_ctx& operator=(Queue_ctx&& other)
{
std::scoped_lock lock{ qu_mutex, other.qu_mutex };
qu = std::move(other.qu);
return *this;
}
void push(const std::vector<std::byte>& v)
{
std::unique_lock lock{ qu_mutex };
qu.push(v);
}
void push(std::vector<std::byte>&& v)
{
std::unique_lock lock{ qu_mutex };
qu.push(std::move(v));
}
};
https://godbolt.org/z/xn6orTedz
It compiles, but more testing is required. Note some functionality is missing to utilize qu_cv
.