Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不同编译器上的不同输出_C++ - Fatal编程技术网

C++ 不同编译器上的不同输出

C++ 不同编译器上的不同输出,c++,C++,为什么下面的代码在不同的编译器上打印不同的结果 #include <iostream> void foo() { std::cout << "::foo() \n"; } namespace Foo { struct Bar { friend void foo() { std::cout << "Bar::foo() \n"; } void bar() { foo(); } void baz(); };

为什么下面的代码在不同的编译器上打印不同的结果

#include <iostream>

void foo() { std::cout << "::foo() \n"; }

namespace Foo
{
   struct Bar
   {
      friend void foo() { std::cout << "Bar::foo() \n"; }
      void bar() { foo(); }
      void baz();
   };

   void Bar::baz() { foo(); }
}

int main()
{
   Foo::Bar instance;
   instance.bar();
   instance.baz();
}
MSVC-10.0

MSVC-11.0

谁是对的?为什么会这样?

我认为gcc是正确的:

C++11中的7.3.1.2/3:

如果在非- 本地类首先声明友元类或 函数是最内层封闭命名空间的成员。姓名 通过不合格查找(3.4.1)或合格查找未找到朋友 查找(3.4.3),直到在该 命名空间范围(在类定义之前或之后

C++03在同一个地方有类似的语言

我不知道为什么MSVC-11找不到
::foo
,但我想你可以阅读这篇文章,意思是根本找不到名称
foo
。我想它的意思是,在最里面的封闭名称空间中找不到名称,但在外部范围中拼写相同的名称可以。但是如果微软想这样做的话我不是他们争论的对象

MSVC-10是错误的,因为它发现了一个标准明确规定的名称,但没有找到。因此,对MSVC-11行为的解释可能很简单,就像“它在10年被报告为一个bug,他们试图修复它,但做得太过分了”

无论如何,修复方法是在命名空间
foo
中引入
foo
声明:

namespace Foo
{
   void foo(); // this is a matching declaration
   struct Bar
   {
      friend void foo() { std::cout << "Bar::foo() \n"; }
      void bar() { foo(); }
      void baz();
   };

   void Bar::baz() { foo(); }
}
名称空间Foo
{
void foo();//这是一个匹配的声明
结构条
{

福友友(){std::cout Btw,你打印了
Bar::foo
,但是这里定义的函数是
foo::foo
。它是命名空间
foo
中的一个免费函数,不是
Bar
的成员@Steve Jessop哦,是的,谢谢。但这不是我的问题。所以,在这种情况下,我怎么能调用friend函数?@Nikita:放一个匹配的d类定义之前的命名空间范围中的eclaration。还要注意,ADL可以找到AFAIK这样的友元函数(也就是说,如果它有任何相关参数,它可以找到),这就是为什么不需要将运算符重载与其定义分开声明为友元的原因。我说“AFAIK”ADL发现了它:这是我引用的位之后的下一句话:-)请,您能发布一个“在类定义之前在命名空间范围中进行匹配声明”的示例吗?您的意思是这样的吗?
Bar::foo()
Bar::foo()
error C3861: 'foo': identifier not found
error C3861: 'foo': identifier not found
namespace Foo
{
   void foo(); // this is a matching declaration
   struct Bar
   {
      friend void foo() { std::cout << "Bar::foo() \n"; }
      void bar() { foo(); }
      void baz();
   };

   void Bar::baz() { foo(); }
}