作为值的引用使用unordered_map

10
有一个值类型为引用的unordered_map是否合法?例如,std :: unordered_map 。我已经成功在VS2013上编译了它,但是不确定它是否应该这样做,因为它会导致一些奇怪的运行时错误。例如,当尝试删除元素时,将抛出“向量下标越界”异常。通过搜索发现,您不能拥有一个引用的vector,但我找不到任何关于unordered_map的信息。
更新:进一步实验表明,“向量下标越界”与引用的unordered_map无关,而是我的代码中的错误。

1
只需使用std::reference_wrapper - T.C.
10
您可以声明这样一个映射,大多数但不是所有的操作都应该可以工作。由于operator[]需要映射类型为DefaultConstructible(而引用并不是),因此您无法使用operator[]。 您也无法使用花括号初始化此映射或将一个映射分配给另一个映射 ,因为它要求映射类型为CopyAssignable - Igor Tandetnik
1
@Igor 大多数容器不需要 (Copy/Move)Assignable,它们可以很好地使用 (Copy/Move)Constructible 和赋值或大括号初始化。map 的 operator[] 是唯一需要 DefaultConstructible 和 (Copy/Move)Assignable 的例外。 - galop1n
1
@galop1n 嗯,对于特定的编译器和标准库实现来说,这可能并不是必需的。但是利用这种灵活性的程序不是有效的C++11程序。从实际角度来看,它是不可移植的;它恰好可以在这个实现中工作,但不能保证在其他符合规范的实现中工作。 - Igor Tandetnik
1
@IgorTandetnik,你应该把你的第一条评论写成答案,它非常有用,我很乐意点赞。 - Miljen Mikic
显示剩余6条评论
1个回答

6

mapunordered_map 都能良好地处理引用,这里有一个可行的例子

#include <iostream>
#include <unordered_map>

using UMap = std::unordered_map<int,int&>;

int main() {
    int a{1}, b{2}, c{3};
    UMap foo { {1,a},{2,b},{3,c} };

    // insertion and deletion are fine
    foo.insert( { 4, b } );
    foo.emplace( 5, d );
    foo.erase( 4 );
    foo.erase( 5 );

    // display b, use find as operator[] need DefaultConstructible
    std::cout << foo.find(2)->second << std::endl;

    // update b and show that the map really map on it
    b = 42;
    std::cout << foo.find(2)->second << std::endl;

    // copy is fine
    UMap bar = foo; // default construct of bar then operator= is fine too
    std::cout << bar.find(2)->second << std::endl;
}

似乎无法使用对象。尝试使用std :: thread,但只会给我error:value-initialization of reference type ‘std::thread&’ - Cerin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接