2009-11-22 93 views
3

我有下面的代碼:友元函數,GCC不能編譯

文件:foo.h中

class Foo { 
    friend void Bar(); 
}; 

文件:Foo.cpp中

void Bar() {}; 

文件Test.cpp

#include "Foo.h" 

int main(void) { 
    Bar(); 
    return 0; 
} 

VS2008 c ompiles沒有任何錯誤或警告。 G ++ 4.3.4報告:

test.cpp: In function ‘int main()’: 
test.cpp:8: error: ‘Bar’ was not declared in this scope 

爲什麼?

回答

2

我在「未答覆」部分中找到此問題,但對以前不正確答案的評論確實構成正確答案。因此,這裏是一個社區wiki對這個內容的迴應。

總結:GCC似乎拒絕良好的代碼。

在類內定義朋友函數(不僅聲明)時的情況由11.4.5覆蓋(「函數可以在類的朋友聲明中定義當且僅當該類是非本地類,函數名稱是不合格的,函數具有名稱空間範圍「 - 您的示例滿足這些要求)。我想這個標準確實允許在類中聲明一個朋友函數(「原型」)。這是g ++產生的錯誤讓我困擾。 - liori 11月22日在20:35

而且11.4.3:「在一個朋友先聲明聲明的函數有外部鏈接,(3.5)否則,函數保留其以往的關聯(7.1.1)。」我認爲這會達成協議。 - Potatoswatter 0秒前[刪除此評論]

1

一個friend聲明不能算作一個原型。您還需要一個單獨的原型:

// File: Foo.h 

void Bar(); 

class Foo { 
    friend void Bar(); 
}; 
+0

你能證明,即與C++標準的參考?我找不到那個。 – liori 2009-11-22 20:08:34

+0

什麼是struct X {friend operator <<(std :: ostream&os,const X&x){os <<「foo」;}};'?在'friend'聲明中爲類模板定義一個流操作符是一個很常見的習慣用法,並且確實足夠調用操作符。 – sbi 2009-11-22 20:30:05

+0

sbi,在類內定義朋友函數(不僅聲明)時的情況由11.4.5覆蓋(「函數可以在類的朋友聲明中定義當且僅當該類是非本地類時,函數名稱是不合格的,函數具有名稱空間範圍「 - 您的示例滿足這些要求)。我*猜測*該標準確實允許類內部的朋友函數的聲明(「原型」)。這是g ++產生的錯誤讓我困擾。 – liori 2009-11-22 20:35:01

-2

你們與標準的知識搖滾,這是事實。但標準是標準的,與標準的實施是完全不同的東西。我想你們一直只使用一個編譯器,就像MSVC一樣,它似乎遵循標準。雖然有很多其他編譯器在那裏。

對於我和我在C/C++中5年的經驗,這很明顯,Test.cpp沒有看到Bar,因爲它只包含Foo.h,沒有Bar的聲明。

我給了約翰Kugelman +1,因爲他的回答解決提出的問題。它不會以知識標準的垃圾郵件。

+0

嗯,我使用多個編譯器來編譯我的代碼庫。在此期間,我偶然發現了這個確切的問題。所以這讓我感到困擾,我願意花一些時間讓GCC的人解決問題,如果它在他們這邊。我只是對標準感覺不太好,想先問這裏。 – liori 2009-12-23 13:19:01