具有私有构造函数的 unordered_map 值类型
Posted
技术标签:
【中文标题】具有私有构造函数的 unordered_map 值类型【英文标题】:unordered_map value type with private constructor 【发布时间】:2015-08-26 12:23:42 【问题描述】:我需要以下代码:
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
?
【问题讨论】:
【参考方案1】:您的错误将指向这一行:
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
上进行第二次查找。
【讨论】:
你不需要在 myclasses 中测试 str 是否存在。 Emplace 不会添加 str 除非它不存在。 @Brahim 这是否正确取决于myclass
的构建成本。
@Barry 这个问题正在N 3873 Improved insertion interface for unique-key maps 中通过添加emplace_or_update
和emplace_stable
方法或在N4006 An improved emplace() for unique-key maps 中通过更改emplace
来解决。
@IlyaPopov 两者都不相关,因为 make_myclass
是必须构造 myclass
的那个。不管emplace
和家人最终看起来如何,我们都必须通过myclass
... 这可能很昂贵。
确实,在这种特殊情况下它没有帮助。以上是关于具有私有构造函数的 unordered_map 值类型的主要内容,如果未能解决你的问题,请参考以下文章
编写Rectangle(矩形)类.该类具有double类型的私有实例变量
基类 'QAbstractListModel' 具有私有复制构造函数