[英]Returning const reference to temporary behaves differently than local const reference?
我試圖更好地了解左值和右值是如何作為引用處理的,所以我創建了這個玩具示例:
#include <iostream>
struct Val
{
Val(int num) : num(num){};
~Val()
{
std::cout << "Destructing with value " << num << std::endl;
}
int num;
};
const Val &test(const Val &val)
{
return val;
}
int main()
{
std::cout<< "Creating foo with value 5" <<std::endl;
const Val &foo = test(Val(5));
std::cout<< "Creating bar with value 3" <<std::endl;
const Val &bar(3);
std::cout<< "Finishing main function" <<std::endl;
return 0;
}
這打印出來:
Creating foo with value 5
Destructing with value 5
Creating bar with value 3
Finishing main function
Destructing with value 3
本質上,我們看到這個右值Val(5)
綁定到函數test
const 引用參數val
,並且返回了相同的值——但是,析構函數被立即調用,因為它是臨時的。 但是當我們嘗試構造Val(3)
並分配給一個 const 引用時,它仍然在整個塊的范圍內。
我的想法是,我們可以將右值綁定到 const 引用,這會延長它們的生命周期,直到該引用超出范圍,但這里似乎不一定如此。 我很感激任何對我誤解的地方的見解。
鑒於const Val &foo = test(Val(5));
,臨時Val(5)
將在完整表達式后立即銷毀,其生命周期不會延長到引用foo
的提升時間。 它不直接綁定到foo
,而是綁定到test
的引用參數。
在參考初始化中,
(強調我的)
每當引用綁定到臨時對象或其子對象時,臨時對象的生命周期都會延長以匹配引用的生命周期,但以下情況除外:
- 在包含該函數調用的完整表達式結束之前,函數調用中引用參數的臨時綁定一直存在:如果函數返回一個引用,該引用比完整表達式的生命周期長,則它成為懸空引用。
通常,不能通過“傳遞”來進一步延長臨時文件的生命周期:從臨時文件綁定的引用初始化的第二個引用不會影響其生命周期。
我的想法是,我們可以將右值綁定到 const 引用,這將延長它們的生命周期,直到該引用超出范圍
是的,確實val
參數確實延長了Val(5)
的生命周期,但是當test
返回時, val
本身被銷毀,並且沒有任何東西可以讓Val(5)
繼續存活,所以它也被銷毀了。
通過引用返回,您實際上返回了一個懸空引用,因此您具有未定義的行為:參數val
是對實際參數Val(5)
的引用這一事實不會影響val
在test
返回后不再可用的事實,並且您正在通過引用返回(好吧,試圖返回)它( val
),而不是它的引用實體。
當您向 test() 本身添加輸出時
const Val &test(const Val &val)
{
std::cout << "test with value " << val.num << '\n';
return val;
}
你會看到,臨時變量一直存在到函數結束,但不會超過
Creating foo with value 5
test with value 5
Destructing with value 5
Creating bar with value 3
Finishing main function
Destructing with value 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.