2016-01-22 56 views
6

我感到有点犯难标准管辖本案例:的std ::移动和映射分配

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)?或者是这个代码安全,没有未定义的行为

+1

这不是UB,但不能保证正常工作,无论是。 –

+0

请参阅[本](http://coliru.stacked-crooked.com/a/5ef8993192148d84)简化版代码。 'std :: map'和赋值运算符不需要参与这种情况发生,并且它们的存在不会改变代码的基本问题。 – Mankarse

+0

@Mankarse,是的,的确,一切都可以归结为这种情况 – GreenScape

回答

11

地狱号码。表达是肯定的,相当于

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

但还有的(bar.operator[](baz)).operator=评价之间没有保证的顺序 - 正式,指定功能后缀表达式被称为 - 和的初始化的评价自变量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")); 
+1

谢谢!这是我以为我自己,只是想从其他人的确认。 – GreenScape