构建一个持有引用的unordered_map是否合法

Is it legal to construct an unordered_map holding references?

本文关键字:unordered map 是否 引用 一个 构建      更新时间:2023-10-16

一般来说,STL容器不能容纳非CopyAssignable类型,如引用。如果我以不应进行复制的方式构造容器,那么代码是否有效。它使用std=c++11编译,并使用某些版本的 gcc-7.2 进行c++14编译,但以下内容是否有效,或者我可以期望它因库升级而中断?在这种情况下,我应该使用reference_wrapper吗?

#include <unordered_map>
struct S {};
void use (S&) {}
void test() {
    S s1, s2;
    const std::unordered_map<int, S&> m{{0, s1}, {1, s2}};
    use(m.at(0));
}

编辑我确实需要参考标准。对我有用也是不够的,如果编译器/标准库的符合标准的更新可以破坏代码。因此,为"以参考为价值unordered_map"给出的答案对我来说是不够的。

我想

我自己为这个特定的用例找到了答案:

第23.5.4.3条C++11标准中关于unordered_map元素访问特别省略了列出mapped_type的任何要求,即S&,而operator[]必须DefaultConstructible

mapped_type& at(const key_type& k);
const mapped_type& at(const key_type& k) const;

返回:对 x.second 的引用,其中 x 是键等效于 k 的(唯一)元素。

抛出:类型 out_of_range 的异常对象(如果不存在此类元素)。

C++17在26.5.4.3和26.5.4.4中也间接地说明了这方面的内容。

因此,上面的代码应该适用于任何标准实现。

但是,正如评论中所指出的,在构造后改变容器或应用任何需要构造或分配容器value_typemapped_type的算法是行不通的。