1

In the following code, I would like whatever type I pass through to MyStruct to be declared as a friend of that structure. I anticipate having many different types being passed through and I don't want to have to manually add each one as a friend, like I have shown for the two current possible classes. I cannot figure out the syntax for this, can someone tell me please?

template<typename MyStructType>
struct OTHER_SUB_TYPE {
  OTHER_SUB_TYPE(MyStructType* p) {  p->private_function(); }
  // Need to access other private members of MyStructType
};

template<typename MyStructType>
struct DEFAULT_SUB_TYPE {
  DEFAULT_SUB_TYPE(MyStructType* p) { p->private_function(); }
  // Need to access other private members of MyStructType
};

template<template<typename> class SUB_TYPE = DEFAULT_SUB_TYPE>
struct MyStruct {
  SUB_TYPE<MyStruct> Get() { return SUB_TYPE{this}; }

  // Would like to avoid having to declare each type individually!
  template<typename T> friend struct DEFAULT_SUB_TYPE;
  template<typename T> friend struct OTHER_SUB_TYPE;

private:
  void private_function() {}
};


int main() {

  MyStruct<> def;
  def.Get();

  MyStruct<OTHER_SUB_TYPE> other;
  other.Get();
}
Wad
  • 1,454
  • 1
  • 16
  • 33
  • 1
    No offense, but that sounds like a horribly flawed design. – πάντα ῥεῖ Jul 11 '22 at 18:47
  • @πάνταῥεῖ, none taken :) If you take a look at the [related question](https://stackoverflow.com/q/72943196), perhaps you can see why this flawed design is apparently necessary. If you have a workaround, then please do share :) – Wad Jul 11 '22 at 20:25
  • I've seen all of your related questions regarding your quite actual problems, and thought that from the beginning. Again: No offense. – πάντα ῥεῖ Jul 11 '22 at 21:19

1 Answers1

2

A solution is to declare a common base class Wrapper as a friend of MyStruct and the wrap the private function. Declare xxx_TYPE as a derived class of this common class Wrapper.

template <typename T>
struct Wrapper {
    void private_function(T* p) {
        p->private_function();
    }
protected:
    Wrapper() = default;
};

template<typename MyStructType>
struct OTHER_SUB_TYPE: Wrapper<MyStructType> {
  OTHER_SUB_TYPE(MyStructType* p) {
      this->private_function(p);
   }
  // Need to access other private members of MyStructType
};

template<template<typename> class SUB_TYPE = DEFAULT_SUB_TYPE>
struct MyStruct {
  SUB_TYPE<MyStruct> Get() { return SUB_TYPE{this}; }

  template<typename T> friend struct Wrapper; // Wrapper as a friend class

private:
  void private_function() {}
};

Demo

Nimrod
  • 2,908
  • 9
  • 20