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"));
source share