返回从成员映射的迭代器中获取的const引用是否安全?

时间:2015-08-19 08:10:40

标签: c++ memory-management reference

如果_mapstd::unordered_map类型的成员,是否可以安全地从函数返回 _map.find(k)->second的引用,或者是否为此未定义的行为(或者只是不好的做法)?

它似乎按预期工作,但感觉有点像返回对临时的引用。我不确定这是否属实,或者是否会产生其他意外后果。

#include <unordered_map>
class Container
{
public:
    using Key = int; // or something more interesting

    // ++++++++++++++++++++++++++++++++++++++++++
    // | Is it safe to return a reference here? |
    // ++++++++++++++++++++++++++++++++++++++++++
    const std::string& get(const Key& k) const
    {
        auto it = _map.find(k);
        return it->second;
    }

    void put(const Key& k, const std::string& v) {
        _map.emplace(k, v);
    }

private:
    std::unordered_map<Key, std::string> _map;
};

int main(int argc, const char * argv[])
{
    Container c;
    c.put(42, "something");

    auto str = c.get(42);

    std::cout << "found " << str << std::endl;
    return 0;
}

3 个答案:

答案 0 :(得分:3)

如果返回的引用的节点保证保留在内存位置(检查容器的文档),或者在返回引用后未修改映射,则返回引用与返回一样安全对任何成员的引用 - 它通常很好但如果对象本身超出范围,对其成员的引用(某人可能会缓存)也已死亡

答案 1 :(得分:3)

查看iterator invalidation的文档。在执行使迭代器无效的操作(例如调用clearinsert)之前,您的引用将保持有效。请注意,如果您使用std::map而不是std::unordered_map,那么迭代器将保持有效,直到从容器中删除该元素。

答案 2 :(得分:-1)

返回本地成员变量的const引用是不安全的。在函数范围之外将释放本地成员变量,而其他程序可以使用其内存。没有其他程序使用本地成员变量的内存,因此它按预期工作。但它无法控制且不安全。你应该改成这样:

std::string get(const Key& k) const