簡體   English   中英

返回對臨時的常量引用的行為與本地常量引用不同?

[英]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)的引用這一事實不會影響valtest返回后不再可用的事實,並且您正在通過引用返回(好吧,試圖返回)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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM