如何将全局范围函数声明为命名空间类的朋友?

Sto*_*row 0 c++ namespaces friend friend-function

以下代码class Foonamespace Namespace.

// main.cpp
#include <csignal>

namespace Namespace
{

class Foo
{
private:
  void doSomething() {};

friend void func( union sigval );
};

}

static Namespace::Foo foo;

void func( union sigval sv ) {
  (void)sv;
  foo.doSomething();
}
Run Code Online (Sandbox Code Playgroud)

我想和void func( union sigval )这个类交个朋友,这样它就可以调用一个私有函数。执行此操作的正确语法是什么?以上失败并出现以下错误

$ g++ --version && g++ -g ./main.cpp
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

./main.cpp: In function ‘void func(sigval)’:
./main.cpp:22:19: error: ‘void Namespace::Foo::doSomething()’ is private within this context
   foo.doSomething();
                   ^
./main.cpp:11:8: note: declared private here
   void doSomething() {};
        ^~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

这个变化...

friend void ::func( union sigval );
Run Code Online (Sandbox Code Playgroud)

...导致此错误:

$ g++ -g main.cpp
main.cpp:13:34: error: ‘void func(sigval)’ should have been declared inside ‘::’
 friend void ::func( union sigval );
                                  ^
Run Code Online (Sandbox Code Playgroud)

sco*_*001 5

您可以仅使用::. 所以你的朋友声明可以是:

friend void ::func( union sigval );
Run Code Online (Sandbox Code Playgroud)

但是不要忘记在类中引用它之前转发声明该函数!

因此,在全局范围内,您将需要:

void func( union sigval );
Run Code Online (Sandbox Code Playgroud)

在类声明之前。

编译示例:https : //ideone.com/hDHDJ8

  • 如果一个类声明了一个没有命名空间限定符的友元函数,并且该函数尚未声明,则该函数将在与该类相同的命名空间中声明。要通过名称引用命名空间限定的全局函数,它必须已被声明。 (2认同)