Home > Software engineering >  Make all types passed as template-template argument a friend
Make all types passed as template-template argument a friend

Time:07-12

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

CodePudding user response:

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

  • Related