Search code examples
c++namespacesfriend

Friend function can no longer access private data members of class after class is encapsulated in namespace


I have a class called Circle that I encapsulated inside a namespace.

namespace my_name_space {
    class Circle;
}

class my_name_space::Circle {
private:
    double radius;
public:
    friend std::ostream& operator << (std::ostream &os, const Circle &c);
};

Here is the function in the implementation file:

std::ostream& operator << (std::ostream &os, const Circle &c)
{
    os << "Radius: " << c.radius;

    return os;
}

Before encapsulating the class within the namespace, everything was working fine. Now the friend function can no longer access the private data members. I don't understand what's wrong.


Solution

  • When you declare operator << as the friend of Circle, it'll become the member of the innermost enclosing namespace of Circle. That means when you put Circle into namespace my_name_space, operator << becomes the member of namespace my_name_space too. The definiton of operator<< doesn't match that, it defines operator<< at globle scope.

    A name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X

    You can move the definition of operator<< into namespace my_name_space:

    namespace my_name_space {
        std::ostream& operator << (std::ostream &os, const Circle &c) {
            ...
        }
    }
    

    Or if you still want to keep operator<< at global scope:

    // delcaration
    std::ostream& operator << (std::ostream &os, const my_name_space::Circle &c);
    class my_name_space::Circle {
        ...
        friend std::ostream& ::operator << (std::ostream &os, const Circle &c);
        //                   ~~
    };
    // definition
    std::ostream& operator << (std::ostream &os, const my_name_space::Circle &c) {
        ...
    }