2016-01-22 68 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