[英]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;
^
因此編譯器不允許在函數聲明中使用不完整類型作為返回值。 解釋是什么?
正如你自己所說的那樣“允許在函數聲明中使用不完整類型作為返回值”。 這正是編譯器允許你做的事情。 您在非定義函數聲明中成功使用了不完整的返回類型 - 您在fh
的f
聲明編譯時沒有任何問題。
但這就是你被允許做的一切。 這絕不會改變以下事實:
在你的代碼中,在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.