c++ - 具有私有(private)构造函数的 unordered_map 值类型

标签 c++ c++14 unordered-map

我需要以下代码:

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() 是私有(private)的。

所以我想我会放置 std::pair 并使它成为 friend :

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];
}

但是仍然得到关于构造函数是私有(private)的错误。

我怎样才能拥有一个具有私有(private)构造函数的类型的 std::unordered_map

最佳答案

您的错误将指的是这一行:

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 上进行第二次查找。

关于c++ - 具有私有(private)构造函数的 unordered_map 值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32226597/

相关文章:

c++ - 如何修复 "Invalid read of size 8 - 40 bytes inside a block of size 64 free' d"

c++ - 允许对具有相同底层结构的类型进行隐式转换

c++ - unordered_map 相同键的迭代顺序

c++ - 什么时候使用 std::unordered_map::emplace_hint?

c++11 - 迭代 unordered_map C++

c++ - 如何在基于范围的for循环中找到当前对象的索引?

c++ - 什么是支持 vector 数学和复数的良好开源 C/C++ 数学库?

c++ - sfinae 远离破坏者

c++ - 为什么在使用 unordered_map 的 emplace 方法时会出现编译错误?

c++ - LoadBitMap() API 会产生绘画问题吗?