我对标准如何管理这种情况感到有点困惑:
struct Foo {
Foo & operator = (std::string xxx)
{
x = std::move(xxx);
return *this;
}
std::string x;
};
std::map<std::string, Foo> bar;
std::string baz = "some string";
bar[baz] = std::move(baz);
编译器可以生成代码,以便{<1}}在之前移动,用于初始化并引用baz
中的元素(初始化bar
)?或者这段代码是否安全,并且没有未定义的行为?
答案 0 :(得分:11)
地狱没有。表达式是,等同于
(bar.operator[](baz)).operator=(std::move(baz))
但是(bar.operator[](baz)).operator=
的评估之间没有保证顺序 - 正式地, postfix-expression 指定要调用的函数 - 以及初始化的评估参数到operator=
,这是从baz
移动的。
事实上,this asserts on GCC:
std::map<std::string, Foo> bar;
std::string baz = "some string";
bar[baz] = std::move(baz);
assert(bar.count("some string"));