2012-04-10 53 views
1

我有兩個文件,my_program.cpp及其標題my_program.h奇怪的C++行爲涉及iostream和wstring

my_program.cpp包含此:

#include "my_program.h" 
using namespace std; 

my_program.h包含一個指向它返回一個wstring一個函數,如下所示:

using namespace std; 
typedef wstring (*my_function)(wstring, int, int, int, int); 

程序不在此狀態下進行編譯(停止在typedef ...說ISO ISO禁止'wstring'沒有類型的聲明),但如果我添加#include <iostream>之前#include "my_program.h"在.cpp文件,該程序奇蹟般地編譯。

爲什麼會發生這種情況?我只是希望我沒有犯下愚蠢的錯誤,現在我會被嘲笑。

+0

我不能完全讀取這個typedef聲明,但是...在那個typedef中你的新的typename在哪裏? – Frizi 2012-04-10 18:42:54

+1

你在'my_porgram.h'中有'#include '嗎? – scientiaesthete 2012-04-10 18:43:04

+1

@Frizi'my_function'是typedef的名稱。它是一個指向返回wstring並具有wstring,int,int ...作爲參數的函數的指針。 – 2012-04-10 18:44:47

回答

5

你真的應該包括<string>

從事物的聲音,你的編譯器的<iostream>恰巧包括<string>,所以它的工作原理,但在不同的編譯器,它可能不會。 C++允許標準頭包含其他標準頭,但不需要它。在某些情況下,你只能得到班級的聲明,所以有些事情有效,而有些則不行。

至少根據我的經驗,這也是一個可能會從編譯器版本變化到下一個版本的問題,所以即使您不打算移植到其他任何東西,您的代碼也可能會停止工作除非你包含正確的頭文件,否則這個過程看似微不足道。

+0

我的不好。我應該知道的。非常感謝你。 – 2012-04-10 18:48:57

0

在添加#include <iostream>,編譯器不知道是什麼wstring - 因此錯誤

後您包括iostream頭,(定義std::wstring - 可能通過其他頭,它包括),編譯器知道wstring指的是什麼,可以正確解析typedef

有一點要記住,編譯器只關心所謂的編譯單元(.cpp文件),而不是頭文件;頭文件在編譯單元包含它們時發揮作用(想想逐字複製粘貼)。因此,您可以在typedef之前的任何地方包括iostream(或其他人指出<string>),以使其起作用 - 從這個角度來看,包括它在標題計數與在標題的第一行包括它相同之前。

然而,將頭標儘可能地自行保持一致通常是一個好主意(所以在你的頭文件中包含相關頭文件而不是.cpp文件),所以包含者不需要記住什麼其他頭文件也包括在內,以使其按預期工作。

+0

我在cpp中的'#include「my_program.h」'之前移動了'using namespace std;',它是一樣的。 – 2012-04-10 18:45:33

+0

不確定你的意思是「它是相同的」,但是「using namespace std;'聲明」將'std'名字空間中的所有東西都提升到了全局名字空間中,所以你不必用'std'例如'wstring'而不是'std :: wstring') - 只要它位於'include '之後和'typedef之前,它在.cpp或header中就不會有什麼區別' – Attila 2012-04-10 18:55:01