我需要以下代码:
class myclass{
private:
myclass(){}
friend myclass *make_myclass(const std::string&);
};
std::unordered_map<std::string, myclass> myclasses;
myclass *make_myclass(const std::string &str){
if(myclasses.find(str) == myclasses.end())
myclasses.emplace(str, myclass{});
return &myclasses[str];
}
但是编译此代码会发出一个很长的错误,即myclass()
是私有的。
所以我想我会把std::pair
放在一边,然后把它变成朋友:
class myclass{
private:
myclass(){}
friend myclass *make_myclass(const std::string&);
friend class std::pair<std::string, myclass>;
};
std::unordered_map<std::string, myclass> myclasses;
myclass *make_myclass(const std::string &str){
if(myclasses.find(str) == myclasses.end())
myclasses.emplace(
std::piecewise_construct,
std::forward_as_tuple(str),
std::forward_as_tuple()
);
return &myclasses[str];
}
但是仍然得到关于构造函数是私有的错误。
如何让std::unordered_map
的类型具有私有构造函数?
答案 0 :(得分:2)
您的错误将引用此行:
return &myclasses[str];
这是因为operator[]
必须默认构建一个值,如果它不在特定键的地图中。由于该运营商不是myclass
的朋友,因此您会收到访问错误。
相反,您应该利用emplace
返回它插入的迭代器的事实:
myclass *make_myclass(const std::string &str) {
auto it = myclasses.find(str);
if (it == myclasses.end()) {
it = myclasses.emplace(str, myclass{}).first;
}
return &it->second;
}
这还有一个额外的好处,就是不必在str
上进行第二次查找。