0

How to conveniently declare many template functions as friend function of a template class?

Example:

template <typename T>
void funct1(MyClass<T> & A); //1.forward declaration.

template <typename T>
class MyClass{
    protected:
    T a;
    friend funct1(MyClass<T> & A); //2.declare friend
}
template <typename T>
void funct1(MyClass<T> & A){ //3.actual implementation
    ++A.a;
}

step 1,2,3 get repeated for each of the many functions....

Is it possible to group all these function into something, then declare everything in that something are friends of the template class?

rxu
  • 1,369
  • 1
  • 11
  • 29
  • 3
    Why there're so many friend functions? Maybe you should reconsider your design. – for_stack Sep 18 '16 at 04:40
  • i am writing a small library for math between n-dimensional array. myclass is a n-dimensional array object. the functions are many math operations that works on the ndarrays. may be i could make all the function into methods of the ndarray object. hmm. but then i get something like A.sin() instead of sin(ndarray A). that feels a bit odd. – rxu Sep 18 '16 at 04:42
  • 1
    Maybe you should expose elements of the array by `iterator` or `operator[]`. It's NOT a good idea to simply make the functions `friend`. Otherwise, each time you add a new function, you'll have to modify `MyClass`. – for_stack Sep 18 '16 at 05:12
  • How to implement a fast iterator/operator[]? So far, I have been using an internal raw pointer to memory with correct simd alignment. – rxu Sep 18 '16 at 13:37
  • `operator[]` is very simple and just returns the element reference at the given index (you can take the implementation of `std::vector` as an example). A decent compiler should inline these functions. So it should be as fast as raw pointer operations. – for_stack Sep 18 '16 at 14:11
  • operator[] of std::vector does bound checking... i was warned to not use that to avoid performance penalty. – rxu Sep 18 '16 at 14:22
  • hmm. i asked a question about iterator performance. iterator looks convenient. If it doesn't break performance, i would try it. http://stackoverflow.com/questions/39558746/iterator-performance – rxu Sep 18 '16 at 14:34
  • `operator[]` of `std::vector` doesn't have bound checking. Instead, the `at` member function has bound checking. Since you're iterating array, a decent implementation of iterator should NOT have obvious performance penalty. Have a benchmark with your code :) – for_stack Sep 18 '16 at 15:01

2 Answers2

2

Yes! You can make them static member functions of a class, and make that class a friend.

template <typename T>
class MyClass{
    protected:
    T a;
    friend class MyFunctions;
}
IanPudney
  • 5,941
  • 1
  • 24
  • 39
2

How about A friend class, all the functions can go into that one friend class:

#include <iostream>

using namespace std;

template <typename T>
class MyFriend;

template <typename T>
class MyClass{
    protected:
      T a;
    public:
      MyClass(T _a):a(_a) {}

    friend MyFriend<T>;
};

template <typename T>
class MyFriend {
  public:
  void funct1(MyClass<T> &A) {
    ++A.a;
    cout << "A.a: " << A.a << endl;
  }

  void funct2(MyClass<T> &B) {
    B.a +=  2;
    cout << "A.a: " << B.a << endl;
  }

};

int main() {
  MyClass<int> myclass(0);
  MyFriend<int> myfriend;

  myfriend.funct1(myclass);
  myfriend.funct2(myclass);

  return 0;
}
bits
  • 1,595
  • 1
  • 17
  • 17