Declaring a namespace as a friend of a class

16.6k views Asked by At

I was wondering if there is a way such that we make all functions defined within a specific namespace friend with a class?

In particular, I have a class, for example:

class C {
    private:
        // ...
    public:
        // ...

        friend C* B::f1(C*);
        friend C* B::f2(C*);
        friend C* B::f3(C*);
        friend C* B::f4(C*);
        friend C* B::f5(C*);
};

and a namespace B as:

namespace B {
    C* f1(C* x);
    C* f2(C* x);
    C* f3(C* x);
    C* f4(C* x);
    C* f5(C* x);
};

Now, I would prefer to avoid writing 5 lines in the class definition to make all five functions of the namespace B friend with class C and just tell the compiler that all of the functions defined within the namespace B are friends with the class C (i.e. can access its private members).

A quick fix I guess is to change the namespace to a class and define the functions as its static members and then declare the class B as a friend of class C. However, out of curiosity I was wondering if such thing is possible with namespaces as well or not?

Thanks in advance.

2

There are 2 answers

7
Angew is no longer proud of SO On

No, it's not possible befriend a namespace. If nothing else, it would constitute a "security breach," as namespaces can be extended anywhere. So anyone could add an arbitrary function to the namespace and access the class's non-public data.

The closest you can get is the solution you propose, making those functions static members of a class and befriending the class. But then again, why not make them static members of the original class (C in your code) in the first place?

As an aside, if I ran into a need for so many friend functions in my code, it would make think again about my design, hard; I'd take it as a sign I'm doing something wrong.

3
alfC On

If you promote your namespace to a class you can friend many functions at once. It comes with (many) other drawbacks, but you may actually want to have a class B (for other reasons).

class C {
    private:
        // ...
    public:
        // ...

    friend struct B_domain;
};

struct B_domain {
    static C* f1(C* x);
    static C* f2(C* x);
    static C* f3(C* x);
    static C* f4(C* x);
    static C* f5(C* x);
};