C++. How to define template parameter of type T for class A when class T needs a type A template parameter?

China☆狼群 提交于 2019-12-08 06:24:16

Tried reproducing your code, not quite sure what you are trying to achieve. For starters, this is what I modified it to:

   #include <string>   //Added
   #include <map>      //Added
   using namespace std;//Added

   template <class T>
   class Processor {    
      map<string,T> ts;    
      void Process(string str, int i) {        
         ts[str].Do(i);    
      }
   };

   template <class P>
   class Executor {
      Processor<P> &p;    //Was Proc ???
      Executor(P &p) : Processor<P>(p) {}    //Was Proc ???
      void Foo(string str, int i) {
         p.Process(str,i);
      }
      void Execute(string str){}  //Added return type void
   };

   template <class E>
   class Algo {
   public:                 //Added
      static E e;
      void Do(int i) {}
   };

   main () {
      typedef Processor< Algo<int> > PALGO; //Added template argument to Algo
      typedef Executor<PALGO> EPALGO;
      typedef Algo<EPALGO> AEPALGO;

      Executor<PALGO> executor(PALGO());
      AEPALGO::e = executor;
   }

Modified Proc to Processor in Executor definition - (what is Proc?) and gave it template argument, in the typedef Processor> PALGO; Then AEPAGO::E --> thats a template param, not class Algo member - so AEPAGO::e. Now you will get an error that can be more manageable. It needs a copy constructor to convert types.

You can use inheritance.

class X : public Executor<Processor<Algo<X>>> {};

Else, this is not possible.

AFAICS, you cannot do that with the same Executor type. Otherwise you would have to define

Executor<Processor<Algo<Executor<Processor<Algo<...> > > > > >

It might work, if you define it with some other type, provided that makes any sense technically

class X {
...
};

Executor<Processor<Algo<Executor<Processor<Algo<X> > > > > >

or with typedef

class X {...};
typedef Processor<Algo<X> > PALGO;
typedef Executor<PALGO> EPALGO;
typedef Algo<EPALGO> AEPALGO;

Executor<PALGO> executor(PALGO());

Since Executor is a singleton, you can move its definition out of Algo either in it's own singleton class or in Executor. Then make all the Algo function that need to know about Executor template member functions.

template <class P>
class Executor {

    static Executor e;

    P &p;
    Executor(P &p) : Proc(p) {}

    void Bar(string str, int i) {
        p.Process(str,i);
    }

    Execute(string str)
    {
    }

    public:
    static Executor& getE(){ return e;}
} 

class Algo
{

    void Do(int i) {}
    template <class E>
    void Foo()
    {
        E::getE().Execute("xxx");
    }
}

Solved! see comments. //****

#include <string>
#include <map>
#include <iostream>
using namespace std;

template <class T>
class Processor {
public:
    map<string,T*> ts;
    void Process(string str, int i)
    {
        ts[str]->Do(i);
    }
};

template <class P>
class Executor  {
public:
    P &p;
    Executor(P &inp) : p(inp) {}

    void Bar(string str, int i) {
        p.Process(str,i);
    }

    void Execute(string str)
    {
        cout << " Executor::Execute " << str << endl;
    }
};

template <template <class> class E> //**********
class Algo
{
    string str;
public:
    Algo(const string &s) : str(s) {}

    static E<Processor<Algo>> *e; //**********

    void Do(int i) { cout << str << "::Do(" << i <<")"<< endl; }

    void Foo()
    {
        e->Execute(str);
    }
};

template <template <class> class E>
E< Processor<Algo<E> > >* Algo<E>::e;  //**********

int main(int argc, char **argv)
{
    typedef Algo<Executor> EALGO;
    typedef Processor<EALGO> PALGO;
    typedef Executor<PALGO> EPALGO;

    PALGO p;
    EPALGO executor(p);

    EALGO::e = &executor; //**********

    EALGO ealgo1("algo1"), ealgo2("algo2");

    p.ts["algo1"] = &ealgo1;
    p.ts["algo2"] = &ealgo2;
    ealgo1.Foo();
    ealgo2.Foo();
    executor.Bar("algo1",1111);
    executor.Bar("algo2",2222);

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!