class MyClass {
public:
MyClass()
{
std::cout << "default constructor\n";
}
MyClass(MyClass& a)
{
std::cout << "copy constructor\n";
}
MyClass(MyClass&& b)
{
std::cout << "move constructor\n";
}
};
void test(MyClass&& temp)
{
MyClass a(MyClass{}); // calls MOVE constructor as expected
MyClass b(temp); // calls COPY constructor... not expected...?
}
int main()
{
test(MyClass{});
return 0;
}
對於上面的代碼中,我預期無論在測試對象創建()來調用移動的構造,因爲b是右值引用類型(MyClass的& &)。c + +移動的構造不要求右值參考
但是,將b傳遞給MyClasss構造函數並不像預期的那樣調用移動構造函數,而是調用複製構造函數。
爲什麼第二個案例調用拷貝構造函數,即使傳入的參數是MyClass類型& &(r值參考)???
我使用的是gcc 5.2.1。要重現我的結果,您必須將-fno-elide-constructors選項傳遞給gcc以禁用副本優化。
void test(MyClass&& temp)
{
if (std::is_rvalue_reference<decltype(temp)>::value)
std::cout << "temp is rvalue reference!!\n";
else
std::cout << "temp is NOT rvalue!!\n";
}
上面的代碼打印出「溫度是右值引用」,即使溫度而得名。
temp的類型是右值引用類型。
表達'temp'計算結果爲左值refernce,而不是右值引用。你將'temp'聲明爲右值引用並不重要。一個*名爲*的引用永遠是一個左值。 – AnT
@AnT你在C++標準文檔中有任何參考嗎?我非常努力地尋找這條規則的任何參考,但我找不到一個...... – SHH
請參閱** 5表達式**的開頭。全部在5/5,5/6和5/7。特別參見注5/7,它基本上是這樣描述的。此外,鏈接的「重複」鏈接到一個托馬斯貝克爾關於這個話題的文章。 – AnT