Имеется вот такой код:
#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();
}
Output
gcc 4.7.2
::foo()
::foo()
MSVC-10.0
Bar::foo()
Bar::foo()
MSVC-11.0
error C3861: 'foo': identifier not found
error C3861: 'foo': identifier not found
Ну и кто прав? И почему происходит именно так?
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>Ну и кто прав?
gcc
NT>И почему происходит именно так?
http://stackoverflow.com/a/7785935
И в стандарте, после пунктов откуда цитата, есть практически твой пример.
Здравствуйте, Nikita.Trophimov, Вы писали:
NT>Ну и кто прав? И почему происходит именно так?
Внимание! Здесь тонкое различие в том, что френд-функция не только объявлена, но и определена в теле класса.
Из-за этого у компиляторов съезжает крыша на почве того, что в стандарте это место прописано невнятно.
Считать ли френд-функцию принадлежащей области видимости класса, или пространству имён, в котором объявлен класс, или глобальному пространству.
Вот кстати
http://rsdn.ru/forum/cpp/4962972.allАвтор: igna
Дата: 13.11.12
И становится понятно, что именно вбивают компиляторы себе в голову:
VC10 — считает, что определили функцию пространства имён
VC12 — что определили свободную функцию класса, и ломается на ADL
gcc — неважно, что там определили, но ADL его пропускает по той же причине (нет там ничего argument-dependent) и находит глобальную.
Хотя возможно, что gcc и VC10 дважды определили инлайн одну и ту же функцию, и нам просто повезло с генератором кода и/или линкером — могла попасться любая копия.