std::move 和地图分配

std::move and map assignment

我对标准如何管理这种情况感到有点困惑:

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);

编译器能否生成代码,以便 baz 移动到 之前 它用于初始化和获取对 bar 中元素的引用(初始化 std::string xxx)?或者这段代码是否安全并且没有未定义的行为?

地狱号。表达式是,是的,等同于

(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"));