构造一个 unordered_map 持有引用是否合法?

Is it legal to construct an unordered_map holding references?

一般来说,STL 容器不能容纳非CopyAssignable 类型,例如引用。如果我以不应该发生复制的方式构建容器,那么代码是否有效。它使用 std=c++11c++14 与某些版本的 gcc-7.2 一起编译,但以下是否有效,或者我是否可以预期它会随着库升级而中断?在这种情况下我应该使用 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));
}

编辑 我确实需要参考标准。如果 compiler/standard 库的符合标准的更新可以破坏代码,那么对我也有效是不够的。所以 "unordered_map with reference as value" 的答案对我来说还不够。

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

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

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

Returns: A reference to x.second, where x is the (unique) element whose key is equivalent to k.

Throws: An exception object of type out_of_range if no such element is present.

C++17 也在 26.5.4.3 和 26.5.4.4 中间接地表达了这种效果。

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

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