I think gcc is right:
7.3.1.2/3 in C++11:
If a friend declaration in a non-
local class first declares a class or function the friend class or
function is a member of the innermost enclosing namespace. The name of
the friend is not found by unqualified lookup (3.4.1) or by qualified
lookup (3.4.3) until a matching declaration is provided in that
namespace scope (either before or after the class definition
C++03 has similar language in the same place.
I'm not sure why MSVC-11 fails to find ::foo, but I suppose you could read this text to mean that the name foo can't be looked up at all. I think the intended meaning is that the name in the innermost enclosing namespace can't be found, but the identically-spelled name in the outer scope can. But if Microsoft wants to argue the intended meaning I'm not the person they'd argue it with.
MSVC-10 is wrong, because it found a name that the standard specifically says is not found. So the explanation for the MSVC-11 behavior might be as simple as "it was reported as a bug in 10, they tried to fix it and went too far".
Anyway, the fix is to introduce a declaration of foo in namespace 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(); }
}
This makes gcc find the friend function. I haven't tested on any version of MSVC.
Bar::foobut the function being defined there isFoo::foo. It's a free function in namespaceFoo, not a member ofBar.