Given the following code,
#include <iostream>
#include <string>
#include <mutex>
#include <string_view>
#include <unordered_map>
struct sstruct {
std::string content;
std::string_view name;
std::mutex mtx;
sstruct(std::string content_, std::string_view name_)
: content(std::move(content_)), name(name_) {
}
std::string get_content() {
return "";
}
};
int main() {
std::unordered_map<std::string, sstruct> map{
{
"pippo", {"dddd", ""}
}
};
std::cout << map["pippo"].content << std::endl;
}
This doesn't compile with the following error:
C:\Users\alt\Desktop\main.cpp(23): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::unordered_map<std::string,sstruct,std::hash<std::string>,std::equal_to<std::string>,std::allocator<std::pair<const std::string,sstruct>>>'
C:\Users\alt\Desktop\main.cpp(27): note: No constructor could take the source type, or constructor overload resolution was ambiguous
I would like to avoid initializing the mutex in the constructor.
https://godbolt.org/z/eqKG6jac1
CodePudding user response:
The problem is that the class std::mutex
is neither copyable nor moveable.
Consider redesigning of your class like
struct sstruct {
std::string content;
std::string_view name;
static std::mutex mtx;
sstruct(std::string content_, std::string_view name_)
: content(std::move(content_)), name(name_) {
}
std::string get_content() {
return "";
}
};
Otherwise try something like the following
std::unordered_map<std::string, sstruct> map;
auto [it, success] = map.try_emplace( "pippo", "dddd", "" );
if ( success )
{
std::cout << it->second.content << std::endl;
}
and
auto it2 = map.find( "pippo" );
if (it2 != map.end())
{
std::cout << it2->second.content << '\n';
}
or
auto &obj = map.at( "pippo" );
std::cout << obj.content << '\n';
CodePudding user response:
unordered_map::operator[]
There are two cases, the key exists time and the return value; when the key does not exist, a empty value will be inserted, and the type of the value requires a no-argument constructor