簡體   English   中英

為什么復制構造函數在通過const引用傳遞臨時時被調用?

[英]why copy constructor is called when passing temporary by const reference?

我將一個未命名的臨時對象傳遞給使用const ref參數定義的函數。 該類的副本是私有的,我收到編譯錯誤。 我不明白為什么在這種情況下調用復制構造函數。

class A {
public:
  A(int i) {}
private:
  A(const A&) {}
};

void f(const A& a)
{
}

int main()
{
  f(A(1)); // <-- error here: 'A::A(const A&)' is private
}

正如所料,當我將主要更改為:

A a(1);
f(a);

有用。

編輯:編譯器是gcc 4.1.2

表達式A(1)rvalue 5.2.3 [expr.type.conv]。

在使用作為rvalue的表達式初始化const引用(函數參數)時,編譯器可以創建臨時表並將該表達式的值復制到臨時表並將該表達式綁定到該臨時表。 8.5.3 [dcl.init.ref] / 5。

[...]無論副本是否實際完成,用於制作副本的構造函數都應該是可調用的。

請注意,此行為是由於下一版本的C ++中的更改。 在新標准中,從類prvalue初始化的const引用必須直接綁定到引用對象; 在這種情況下,不允許創建臨時文件,並且不使用或不需要復制構造函數。

您可以在需要復制構造函數的臨時對象中找到問題的答案,或直接轉到http://gcc.gnu.org/bugs/#cxx%5Frvalbind

C ++標准說在這個上下文中應該創建一個臨時對象,其內容用我們試圖綁定到引用的對象的副本填充; 它還說可以省略臨時副本,但仍然需要檢查復制構造函數的語義約束(例如可訪問性)。

有關詳細信息,請參閱以下C ++標准段落:[dcl.init.ref] / 5,bullet 2,sub-bullet 1和[class.temporary] / 2。

從GCC 4.3.0開始,GCC不再為此情況提供錯誤。 此更改基於C ++語言委員會的意圖。 截至2010-05-28,C ++ 0x標准的最終提議草案允許此代碼無錯誤。

因為a(1)調用構造函數A(int i),然后在調用void f(const A&)時調用A(const A&)。

使A(int i)構造函數顯式化,您不應該遇到此錯誤。

編輯:我想我誤解了這個問題。 我可能會刪除它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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