0

The following code defines class Foo in namespace 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();
}

I would like to make void func( union sigval ) a friend to this class so that it can call a private function. What is the correct syntax to do this? The above fails with the following error:

$ 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() {};
        ^~~~~~~~~~~

This change...

friend void ::func( union sigval );

...results in this error:

$ g++ -g main.cpp
main.cpp:13:34: error: ‘void func(sigval)’ should have been declared inside ‘::’
 friend void ::func( union sigval );
                                  ^
StoneThrow
  • 5,314
  • 4
  • 44
  • 86

1 Answers1

5

You can reference the global scope with just ::. So your friend declaration can be:

friend void ::func( union sigval );

But don't forget to forward declare the function before you reference it in the class!

So in the global scope you'll need:

void func( union sigval );

Before the class declaration.

Compiled example: https://ideone.com/hDHDJ8

scohe001
  • 15,110
  • 2
  • 31
  • 51
  • I dont understand why the forward declaration is needed. It isn't needed when `func` is also in `Namespace` https://godbolt.org/z/YvWKzs – 463035818_is_not_an_ai Nov 11 '20 at 21:28
  • 2
    If a class declares a friend function without namespace qualifiers, and the function isn't already declared, then the function is declared in the same namespace as the class. To refer to the namespace-qualified global function by its name, it must already be declared. – Chris Uzdavinis Nov 11 '20 at 21:47