Std :: move and assign map

I am a little puzzled by how the standard defines this case:

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

Can compilers create code so that baz moved before it was used for initialization and get a link to an element in bar (to initialize std::string xxx )? Or is this code safe and no undefined behavior?

+6
source share
1 answer

Hell. The expression, yes, is equivalent

 (bar.operator[](baz)).operator=(std::move(baz)) 

But there is no guaranteed order between evaluation (bar.operator[](baz)).operator= - formally, a postfix expression denoting the function to be called - and evaluating the initialization of the argument to operator= , which is what moves from baz .

In fact, this confirms the GCC :

 std::map<std::string, Foo> bar; std::string baz = "some string"; bar[baz] = std::move(baz); assert(bar.count("some string")); 
+11
source

All Articles