0

I'm trying to make a tree structure to manage data whose structure can change depending on the type.

Here is what I did for the base object

//Type1.. are the types of the leaves having Base as common parent
enum class EnumBase{Type1,Type2,Type3};

class Base {
protected:
  EnumBase const _type;
  Base(EnumBase typ) : _type(typ){}
public:
  virtual ~Base() = default;
  Base() = delete;
  EnumBase getType() const {return _type;}
};

while this is to create and get different derived

template<class Leaf>
class Controller {
private:
  std::shared_ptr<Leaf> _pt;
public:
  template<class Derived>
  void create() {
    _pt =  std::make_shared<Derived>();
    return;
  }

  template<class Derived>
  Derived & get(){
    auto pt = std::dynamic_pointer_cast<Derived>(_pt);
    if(!pt){
      throw; //bad cast
    }
    return *pt;
  }
};

The second level of the tree goes like:

enum class Type1Types{T1,T2};

class Type1 : public Base {
protected:
  Type1Types const _type;
  Type1(Type1Types typ) : Base(EnumBase::Type1), _type(typ){}
public:
  virtual ~Type1() = default;
  Type1() = delete;
  Type1Types getType() const {return _type;}
};

class Type2; //...the same with EnumBase::Type2 and Type2Types 

class Type3; //...the same with EnumBase::Type3 and Type3Types

with final implementations which may possibly include Controller for another data type:

class T1 : public Type1 {
public:
  T1() : Type1(Type1Types::T1) {}
  //... data of T1
};

class T2 : public Type1 {
public:
  Controller<Type2> objType2;
  //... other data for T2
};

The idea behind all this is that I can write:

int main(){
  Controller<Type1> obj;
  obj.create<T2>();
  obj.get<T2>().objType2.create<somethinginType2>();
  //...
}

Probably such pattern is overcomplicated (any comment and suggestion is welcomed) but a pattern exists and I believe that it is possible with some template magic and some recursion to write a general templated version of a leaf (Type1, Type2,..) so that I don't have to copy/paste the code and only change the type of the enum for the children (Type1Types) and the type for itself (EnumBase::Type1).

I was thinking of some structure like

template<class Me, class... Parents>
struct MagicStructure{
  //some typedef
  //my type
}

Any idea?

Teloze
  • 279
  • 2
  • 8
  • I'm having trouble understanding the `Option` class declaration. Also, what exactly is your question? – selbie Sep 17 '17 at 16:19
  • The Option class takes as template parameter one of the leaves of the tree, it creates the possible derived and store it in the shared_ptr. It can also get the reference to the derived object. The name Option is probably misleading as well as the template. I'll change it with template Controller. About the question: for each leaf I have to type almost always the same structure with the only difference being the type of the Leaf and what kind of children it has. So I was asking myself if there was any way to generate the code of the Leaf only with a templated class – Teloze Sep 17 '17 at 17:58
  • 1
    I kind of get what you are saying, but you're going down a complicated road that may not lead to the most maintainable code. What you likely want to do is to break down your problem into data (leaf items), data structures (the tree and nodes of the tree), and algorithms (tree traversal). I think you'll find that you'll only need templates for a very small subset of this problem. The rest can be accomplished with simple inheritance (with or without virtual methods). – selbie Sep 17 '17 at 18:14
  • I'll try your idea even if I'm not sure I got everything. You believe it's better to keep data away from the tree structure? – Teloze Sep 17 '17 at 19:49

0 Answers0