Executor class has template of type P and it takes a P object in constructor. Algo class has a template E and also has a static variable of type E. Processor class has template T and a collection of Ts.
Question how can I define Executor< Processor<Algo> >
and Algo<Executor>
? Is this possible? I see no way to defining this, its kind of an "infinite recursive template argument"
See code.
template <class T>
class Processor {
map<string,T> ts;
void Process(string str, int i)
{
ts[str].Do(i);
}
}
template <class P>
class Executor {
P &p;
Executor(P &inp) : p(inp) {}
void Bar(string str, int i) {
p.Process(str,i);
}
Execute(string str)
{
}
}
template <class E>
class Algo
{
static E e;
void Do(int i) {}
void Foo()
{
e.Execute("xxx");
}
}
main ()
{
typedef Processor<Algo> PALGO; // invalid
typedef Executor<PALGO> EPALGO;
typedef Algo<EPALGO> AEPALGO;
Executor<PALGO> executor(PALGO());
AEPALGO::E = executor;
}
EDIT ****************************
A little clarification. Executor is a singleton that provides a service. All Algo objects need the services of Executor. Executor will sometimes generate reports that need to be sent to a specific Algo object. They get sent to the correct Algo through Processor.
Basic issue is that Algo is needed to define Executor and Executor is needed to define Algo.
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);
}