2016-04-22 118 views
4

我在這裏講述了一個長期的背景故事,因爲除了直接的答案之外,我想知道我的推理是否導致這種情況是正確的。爲什麼我需要在臨時dynamic_bitset上調用std :: move?

我有一個函數採取dynamic_bitset<>參數(從Boost.dynamic_bitset)。 說它看起來像這樣。

void foo(boost::dynamic_bitset<> db) { 
    // do stuff 
} 

恰巧,它只會被調用與臨時工,從構造建成,爲foo(boost::dynamic_bitset<>{5}.set())(含5位位集調用所有位設置)。

我的位集只有少量的位(少於32位)。所以起初,我認爲「我只是通過價值傳遞它;副本比指針小。」但後來我想:「它是動態的,所以它必須在堆上分配空間,我想避免不必要的分配和釋放。」

所以,我可以使它

void foo(const boost::dynamic_bitset<>& db); 

但一提的是一個指針,一個來,dynamic_bitset(大概)有一個指向它的數據,所以後來用dbfoo會經歷間接的兩個級別,這似乎愚蠢。很明顯,最好的方法是將指針複製到foo,而不必在堆上重新分配和複製數據。

「啊哈!」我說。 「這當然是語義學的動力。」所以,我改變了簽名

void foo(boost::dynamic_bitset<>&& db); 

但隨後,調用foo(boost::dynamic_bitset<>{5}.set())給出了一個編譯器錯誤,cannot bind 'boost::dynamic_bitset<>' lvalue to 'boost::dynamic_bitset<>&&'。 我必須改爲撥打 foo(std::move(boost::dynamic_bitset<>{5}.set())) 然後一切正常。

爲什麼我需要調用std :: move? 這似乎很明顯是一個xvalue(臨時即將到期),不是嗎?

+1

這不取決於'set'是什麼? –

回答

5

the boost docs

dynamic_bitset& set(); 

set()返回左值。

一般來說,如果通過值的函數返回,或通過右值參考:

dynamic_bitset set(); 
dynamic_bitset&& set(); 

則表達式set()是一個rvalue(在第一種情況下一個prvalue,並且在第二的x值)。但是因爲在實際代碼set()返回一個左值引用,表達式set()是一個左值。

category values http://downloads.sehe.nl/stackoverflow/value-categories.svg

+1

看到,這使我困惑,因爲我認爲沒有分配給任何東西的函數調用的結果總是一個xvalue。移動語義的典型例子似乎總是'takemove(foo())',其中沒有討論'foo()'的返回類型:結果是一個沒有名字的臨時變量,因此是一個xvalue。你是說這隻有在'foo()'不返回引用時纔有效? – Kundor

+0

@Kundor:已更新答案,希望澄清。 –

相關問題