Search code examples
c++namespacesfriendfriend-function

How to declare a global-scope function a friend to a namespaced class?


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 );
                                  ^

Solution

  • 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