我很难理解以下MWE无法编译的原因:
#include <iostream>
namespace N
{
class Foo
{
friend void bar( Foo& f );
void print(){ std::cout << "..." << std::endl; } // private by default
};
}
void bar( N::Foo& f )
{
f.print();
}
int main()
{
}
g ++ 4.8.2错误
Test.cpp: In function ‘void bar(N::Foo&)’:
Test.cpp:8:8: error: ‘void N::Foo::print()’ is private
void print(){ std::cout << "..." << std::endl; } // private by default
^
Test.cpp:14:10: error: within this context
我几乎肯定在这里遗漏了一些东西,但朋友函数bar()
肯定可以访问班级N::Foo
的任何私人成员。
请注意:
bar()
移动到命名空间N
可以解决此错误。::bar()
未调用N::Foo::print()
为什么代码不按原样编译?
修改
第二个想法,这个问题的标题并没有准确地描述问题。我会在适当的时候编辑它。
答案 0 :(得分:5)
非限定友元声明是指包含该类的命名空间中的函数,如果尚未声明该函数,则将该函数引入该命名空间。
我将该功能移到命名空间中。它可以通过参数依赖查找找到,因此您可以使用不合格的bar(foo)
来调用它,而无需N::
。
如果由于某种原因确实需要它在全局命名空间中,那么在将它声明为朋友之前,您需要在全局命名空间中声明它。这有点乱:
// Need the class definition to declare the function
namespace N {class Foo;}
// Need the function definition to declare it a friend
void bar( N::Foo& );
// Need the class definition to define the function
namespace N
{
class Foo
{
friend void ::bar( Foo& f );
void print(){ std::cout << "..." << std::endl; } // private by default
};
}
// And finally the function
void bar( N::Foo& f )
{
f.print();
}