首頁 >後端開發 >C++ >## 將常數參考綁定到臨時物件的子部分是否會延長其生命週期?

## 將常數參考綁定到臨時物件的子部分是否會延長其生命週期?

Susan Sarandon
Susan Sarandon原創
2024-10-29 05:20:30966瀏覽

## Does Binding a Const Reference to a Temporary Object's Sub-part Extend its Lifetime?

臨時物件子部分的 const 引用可以延長物件的生命週期嗎?

考慮以下程式碼片段:

<code class="c++">#include <stdio.h>

struct P2d {
    double x, y;
    P2d(double x, double y) : x(x), y(y) {}
    ~P2d() { printf("Destructor called\n"); }
};

P2d center() {
    return P2d(10, 10);
}

int main(int argc, const char *argv[]) {
    const double& x = center().x;
    printf("x = %.18g\n", x);
    return 0;
}</code>

當使用 GCC 5.2.0 編譯時,P2d 臨時實例在進入 main 中的 printf 呼叫之前被銷毀。儘管如此,x 的值仍被保留並正確列印。換句話說,不是將 x 直接綁定到 P2d 臨時的 x 成員,而是創建第二個臨時雙精度值來複製該成員的值。

另一方面,Clang 將 P2d 臨時的生命週期延長到生命週期x 引用,導致析構函數在 main 中的 printf 之後被呼叫。

這提出了一個問題:這種行為是 GCC 中的錯誤還是標準允許的?

分析

CWG 1651 解決了這個問題:

The resolution of issues 616 and 1213, making the result of a member access or subscript expression applied to a prvalue an xvalue, means that binding a reference to such a subobject of a temporary does not extend the temporary's lifetime. [class.temporary] should be revised to ensure that it does.

目前,[class.temporary]/5 指出:「第二個上下文是引用綁定到臨時物件時。因此,在上面的程式碼片段中,center().x 被視為純右值(Clang 和 GCC 都是如此),並且 [class.temporary]/5 不適用。

但是,GCC 和 Clang 有尚未實施DR 1651決議,即N3918。該決議明確指出“應用於臨時表達式的成員訪問和下標表達式會產生臨時表達式”,並補充說“相應的臨時對象(如果有)在引用的生命週期內持續存在。”

因此,根據N3918 的措辭,Clang 似乎正在實現預期的行為,而GCC 則沒有。 DR 60297 指出 GCC 不會延長臨時標量子物件的生命週期,因為它們沒有被 [dcl.init.ref]/(5.2.1.1) 覆蓋。

總之,GCC 中的當前行為是根據標準當前的措辭,這是正確的,但在這種情況下,標準可能會被修改為要求延長使用壽命。 Clang 已經實現了預期的未來行為。

以上是## 將常數參考綁定到臨時物件的子部分是否會延長其生命週期?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn