【发布时间】:2021-01-05 13:07:43
【问题描述】:
我用-std=c++17 构建它并尝试了g++ 和clang++,例如clang++ -std=c++17 <file>。它显示了相同的结果。
unordered_map
将 unordered_map 传递给函数中的右值参数,并将其分配给另一个引用。并且内存是不允许出函数的。
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
using namespace std;
typedef unordered_map<string, string> kw_t;
struct Bar {
kw_t &foo;
string bar;
};
list<Bar> bars;
void test(kw_t &&foo) {
cout << &foo["a"] << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo["a"] << endl;
}
int main()
{
test({{"a", "b"}});
cout << &bars.front().foo["a"] << endl;
return 0;
}
它有输出:
0x1f3ded8
0x1f3ded8
[1] 9776 segmentation fault (core dumped) ./a.o
列表
但是对于其他的类,比如list或者自定义的struct,代码可以工作。
#include <iostream>
#include <list>
#include <string>
using namespace std;
typedef list<string> args_t;
struct Bar {
args_t &foo;
string bar;
};
list<Bar> bars;
void test(args_t &&foo) {
cout << &foo.front() << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo.front() << endl;
}
int main()
{
test({"a", "b"});
cout << &bars.front().foo.front() << endl;
return 0;
}
打印出来了:
0x15a7ec0
0x15a7ec0
0x15a7ec0
为什么第二个可以,第一个不行?
编辑1:
clang 版本 7.1.0
g++ (GCC) 9.3.0
【问题讨论】:
-
您在这两种情况下都创建了一个悬空引用
foo。所以它们都不起作用。 -
@user7860670 但是第二种情况有效。这是编译器的错误行为吗?
-
我认为应该在声明时初始化引用。新版本的 C++ 是否发生了变化?
-
第二个版本不行,和第一个一样。唯一的区别是,在第一种情况下,UB 表现为分段错误。
-
@ArdahanKisbet 所有的引用都在这里正确初始化。
标签: c++ list unordered-map rvalue