3

我有以下代码:

文件:Foo.h

class Foo {
    friend void Bar();
};

文件:Foo.cpp

void Bar() {};

文件测试.cpp

#include "Foo.h"

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

VS2008 编译它没有任何错误或警告。G++ 4.3.4 报告:

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

为什么?

4

3 回答 3

2

我在“未回答”部分找到了这个问题,但对之前错误答案的评论确实构成了正确答案。因此,这是一个包含该内容的社区 wiki 响应。

摘要:GCC 似乎拒绝了好的代码。

11.4.5 涵盖了在类内部定义(不仅声明)友元函数的情况(“当且仅当类是非本地类时,函数才能在类的友元声明中定义,函数名是不合格的,并且该函数具有命名空间范围”——您的示例满足这些要求)。我猜该标准确实允许在类中声明(“原型”)友元函数。困扰我的是 g++ 生成的错误。– liori 11 月 22 日 20:35

同样 11.4.3:“在友元声明中首次声明的函数具有外部链接 (3.5)。否则,该函数将保留其先前的链接 (7.1.1)。” 我认为这可以达成交易。– Potatoswatter 0 秒前 [删除此评论]

于 2009-12-23T07:39:23.853 回答
1

friend声明不算作原型。您还需要一个单独的原型:

// File: Foo.h

void Bar();

class Foo {
    friend void Bar();
};
于 2009-11-22T20:02:18.027 回答
-3

你们对标准的知识很了解,这是真的。但是标准就是标准,标准的实施是完全不同的事情。我猜你们一直只使用一个编译器,比如 MSVC,它似乎遵循标准。虽然那里有大量其他编译器。

对于我和我 5 年的 C/C++ 经验来说,很明显 Test.cpp 没有看到 Bar,因为它只包含没有 Bar 声明的 Foo.h。

我给 John Kugelman +1 是因为他的回答解决了所提出的问题。它不会向标准知识发送垃圾邮件。

于 2009-12-23T09:00:48.663 回答