Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring set of member functions as friend by using template

Given the following code:

class A;

struct B {
    static void doIt(A* pa);
};

struct C {
    static void doIt(A* pa);
};

class A {
    int i = 9;
    // below works but requires a line per each type
    friend void B::doIt(A* pa);
    friend void C::doIt(A* pa);

    // the below however doesn't work
    // template<typename T>
    // friend void T::doIt(A* pa);
      // (gcc error: member 'void T::doIt(A*)' declared as friend before type 'T' defined)
      // (clang just ignores the above and the error is on accessing A::i in B and C)    
};

void B::doIt(A* pa) {
    cout << pa->i << endl;
}

void C::doIt(A* pa) {
    cout << pa->i *2 << endl;
}

int main() {
    A a;
    B::doIt(&a);
    C::doIt(&a);
}

Is it possible to replace the multiple friend declarations to allow all void T::doIt(A* pa) methods access the private members of A?

Trying to instantiate B and C above A doesn't help.

like image 737
Amir Kirsh Avatar asked Oct 30 '22 13:10

Amir Kirsh


1 Answers

Not exactly what do you asked but... if you templatize the B, C, etc. structs, you can get something similar.

#include <iostream>

class A;

template <std::size_t>
struct X
 { static void doIt(A* pa); };

class A
 {
    int i = 9;

    template <std::size_t I>
    friend void X<I>::doIt (A* pa);
 };

template <>
void X<0U>::doIt(A* pa)
 { std::cout << pa->i << std::endl; }

template <>
void X<1U>::doIt(A* pa)
 { std::cout << pa->i * 2 << std::endl; }

template <>
void X<2U>::doIt(A* pa)
 { std::cout << pa->i * 3 << std::endl; }

using B = X<0U>;
using C = X<1U>;
using D = X<2U>;

int main() {
    A a;
    B::doIt(&a);
    C::doIt(&a);
    D::doIt(&a);
}
like image 99
max66 Avatar answered Nov 15 '22 06:11

max66