C++ std::移动和映射分配

C++ std::移动和映射分配,c++,c++11,move-semantics,C++,C++11,Move Semantics,我对standard如何管理这个案例感到有点困惑: 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]

我对standard如何管理这个案例感到有点困惑:

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);
structfoo{
Foo&运算符=(标准::字符串xxx)
{
x=std::move(xxx);
归还*这个;
}
std::字符串x;
};
地图条;
std::string baz=“一些字符串”;
条[baz]=std::move(baz);

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

绝对没有。表达式是,是的,相当于

(bar.operator[](baz)).operator=(std::move(baz))
但是在
(bar.operator[](baz)).operator=
的求值(形式上是指定要调用的函数的后缀表达式)和
operator=
的参数初始化求值之间没有保证的顺序,后者是从
baz
移动的

事实上:

std::映射栏;
std::string baz=“一些字符串”;
条[baz]=std::move(baz);
断言(bar.count(“某些字符串”);

它不是UB,但也不能保证工作。请参阅代码的简化版本<代码>std::map和赋值操作符不需要参与,它们的存在不会改变代码的根本问题。@Mankarse,是的,确实,一切都可以归结为这种情况谢谢!这就是我自己的想法,只是想得到别人的确认。
std::map<std::string, Foo> bar;
std::string baz = "some string";
bar[baz] = std::move(baz);
assert(bar.count("some string"));