Search code examples
c++classnamespacesfriendname-lookup

Global namespace friend class cannot access private member of named namespace class


In a named namespace class, I declare a class (which is in the global namespace) as friend. However, the latter class cannot access the private member of the former class. Why is this? Is there any way around it?

Bob.h

namespace ABC {
    class Bob {
        friend class Joe;
        public:
            Bob ();
            int pub_number;
        private:
            int priv_number;
    };
}

Bob.cc

#include "Bob.h"

ABC::Bob::Bob () {
    pub_number=10;
    priv_number=6;
}

Joe.h

class Joe {
    Joe ( );
};

Joe.cc

#include "Joe.h"
#include <iostream>
#include "Bob.h"

Joe::Joe ( ) {
    ABC::Bob b;
    std::cout << b.pub_number << std::endl;
    std::cout << b.priv_number << std::endl;
}

The above code produces the following error when compiled:

Joe.cc:8:16: error: ‘int ABC::Bob::priv_number’ is private within this context
INFO: 1>     8 | std::cout << b.priv_number << std::endl;

If I do the same code as above, but without any namespace for the "Bob" class, then the code compiles.

I have attempted to forward declare the Joe class in Bob.h as follows:

class Joe; // This does nothing to help

class ::Joe // This produces compiler message "error: ‘Joe’ in namespace ‘::’ does not name a type"

Solution

  • You need add both an unscoped forward declaration in the global namespace, as well as use the scoping operator when declaring the friend:

    class Joe;  // Forward declaration
    
    namespace ABC {
        class Bob {
            friend class ::Joe;  // Use the Joe class from the global scope
            public:
                Bob ();
                int pub_number;
            private:
                int priv_number;
        };
    }