簡體   English   中英

返回函數類型的前向聲明

[英]Forward declaration of returned type of function

正如這個答案所暗示的那樣,我知道允許在函數聲明中使用不完整類型作為返回值。 所以我寫了下面的代碼:

Obj.h

class Obj {
    int x;
};

FH

class Obj;
Obj f();

f.cpp

#include "Obj.h"

Obj f() {
    return Obj();
}

main.cpp中

#include "f.h"
int main() {
    f();
    return 0;
};

使用以下編譯器編譯此代碼:

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)

使用以下編譯命令:

g++ *.cpp

給出以下錯誤:

main.cpp: In function 'int main()':
main.cpp:4:7: error: invalid use of incomplete type 'class Obj'
     f();
       ^
f.h:1:7: error: forward declaration of 'class Obj'
 class Obj;
       ^

因此編譯器不允許在函數聲明中使用不完整類型作為返回值。 解釋是什么?

正如你自己所說的那樣“允許在函數聲明中使用不完整類型作為返回值”。 這正是編譯器允許你做的事情。 您在非定義函數聲明中成功使用了不完整的返回類型 - 您在fhf聲明編譯時沒有任何問題。

但這就是你被允許做的一切。 這絕不會改變以下事實:

  1. 在功能定義時 ,返回類型應完整
  2. 在函數調用時 ,返回類型應完成。

在你的代碼中,在main()你試圖調用一個用不完整的返回類型聲明的函數。 因此錯誤。

5.2.2函數調用[expr.call]

10如果結果類型是左值引用類型或對函數類型的右值引用,則函數調用是左值;如果結果類型是對象類型的右值引用,則為xvalue, 否則為prvalue。

11如果函數調用是對象類型的prvalue:

- 如果函數調用是 - decltype-specifier的操作數或 - 作為decltype-specifier的操作數的逗號運算符的右操作數,則不為prvalue引入臨時對象。 prvalue的類型可能不完整。 [...]

- 否則,prvalue的類型應完整。

換句話說,你被允許的是用不完整的返回類型引入你的函數的早期前向聲明。 但是當你定義該函數或調用它時,你應該完成返回類型。

這里的問題是main.cpp在編譯main.cpp時不知道Obj是什么,因為返回類型不完整而無法調用f 你需要做的是將Obj的定義引入main.cpp 您可以使用main.cpp#include "obj.h"執行此操作。

實例

如您所見,並非所有不完整類型都被允許。 實際上,規則是函數可以返回指向不完整類型的指針或引用 原因是在調用時,編譯器必須能夠生成代碼來處理返回的對象。 當沒有關於對象內容的信息時,編譯器無法生成代碼。 例如,假設Obj有一個非平凡的析構函數; 如果編譯器不知道,它就無法生成破壞對象的代碼。 當返回類型是指針或引用時,編譯器具有所需的所有信息:指針和引用通常不依賴於目標對象的詳細信息。

暫無
暫無

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

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