我正在阅读C ++ Primer,作者说,
“如果在命名空间内定义了一个类,那么另外一个 未申报的朋友 function在同一名称空间中声明:
namespace A {
class C {
public:
friend void f(const C&); // makes f a member of namespace A
};
}
这不是说我不必在命名空间内再次声明函数f()吗?
当我简单地将命名空间外的函数f()定义为
时void
A::f(const C& obj)
{
std::cout << "f(const C&) " << std::endl;
}
我从g ++ 4.5中得到错误,
FriendDeclarations1.cpp:40:23: error: ‘void A::f(const A::C&)’ should have been declared inside ‘A’
有人可以告诉我作者的意思吗?
答案 0 :(得分:3)
作者的意思是如果未明确声明其名称空间,则在同一个类名称空间中隐式声明friend函数。
因此f
需要在命名空间A
#include <iostream>
namespace A {
class C {
friend void f(const C&); // makes f a member of namespace A
int i;
public:
C() : i(42) {}
};
void f(const A::C& obj)
{
std::cout << "f(const A::C&) " << std::endl;
std::cout << "obj.i = " << obj.i << std::endl; // access private member
}
}
int main()
{
A::C ac;
f(ac);
return 0;
}
您可以通过明确声明f
所属的命名空间
#include <iostream>
// forward declarations
namespace A { class C; }
namespace B { void f(const A::C&); }
namespace A {
class C {
friend void B::f(const C&);
int i;
public:
C() : i(42) {}
};
}
namespace B {
void f(const A::C& obj)
{
std::cout << "f(const A::C&) " << std::endl;
std::cout << "obj.i = " << obj.i << std::endl; // access private member
}
}
int main()
{
A::C ac;
B::f(ac);
return 0;
}
答案 1 :(得分:2)
标准7.3.1.2 / 3:
首先在名称空间中声明的每个名称都是该名称空间的成员。如果朋友申报了 非本地类首先声明一个类或函数83)友元类或函数是最里面的成员 封闭命名空间。 在该命名空间范围内(在授予友谊的类声明之前或之后)之前或之后,通过简单的名称查找找不到朋友的姓名。
答案 2 :(得分:0)
对于类声明,您所拥有的内容被解释为类成员定义:
class A {
void f(const C& obj);
}
你应该这样定义:
namespace A {
void f(const C& obj)
{
std::cout << "f(const C&) " << std::endl;
}
}