Объявление пространства имен как друга класса

Мне было интересно, есть ли такой способ, чтобы все функции, определенные в определенном пространстве имен friend, имели класс?

В частности, у меня есть класс, например:

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*);
};

и пространство имен B как:

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

Теперь я бы предпочел не писать 5 строк в определении класса, чтобы сделать все пять функций пространства имен B friend с классом C и просто сообщить компилятору, что все функции, определенные в пространстве имен B являются друзьями класса C (т.е. могут обращаться к своим частным членам).

Быстрое исправление, я думаю, это изменить пространство имен на класс и определить функции как его статические члены, а затем объявить класс B как друга класса C. Однако из любопытства мне было интересно, возможно ли такое с пространством имен или нет?

Спасибо заранее.

Ответ 1

Нет, это не возможно подружиться с пространством имен. Если ничего другого, это будет представлять собой "нарушение безопасности", поскольку пространства имен могут быть расширены в любом месте. Поэтому любой может добавить произвольную функцию в пространство имен и получить доступ к непубличным данным класса.

Ближе всего вы можете найти решение, которое вы предлагаете, делая эти функции статическими членами класса и поддерживая класс. Но опять же, почему бы не сделать их статическими членами исходного класса (C в вашем коде) в первую очередь?

В стороне, если я столкнулся с необходимостью для многих функций для друзей в моем коде, он снова подумает о моем дизайне; Я бы воспринял это как знак, что я делаю что-то неправильно.

Ответ 2

Если вы продвигаете свое пространство имен в класс, вы можете одновременно добавить несколько функций. Он содержит (многие) другие недостатки, но вы действительно можете иметь класс B (по другим причинам).

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

    friend struct B;
};

struct B {
    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);
};