Re: Resolving template parameters
stefan.bruckner@gmail.com wrote:
On Feb 21, 8:08 am, John Harrison <john_androni...@hotmail.com> wrote:
stefan.bruck...@gmail.com wrote:
Hi,
I am looking for a way to achieve the following. I've tried a couple
of things, but they all ended up being too complicated:
I have a templated class A. I want another class B to be able to call
a method defined in A's base class which at runtime determines the
template parameters (I know ahead what is allowed) and calls a
templated member function B with A's template parameters.
I'm imagining something like this - I know that it can't work like
this, but I would like to achieve a similarly simple syntax:
class Base
{
public:
virtual void call(...) = 0;
}
template <class T1,class T2>
class A : public Base
{
public:
void call(...)
{
if (typeid(T1) == ...)
...
else if (...)
...
else if (...)
...
}
}
class B
{
public:
void x()
{
Base *pSomePtr = ...;
pSomePtr->call(this,&B::y);
};
template <class T1,class T2>
void y()
{
// do stuff
};
};
Any help on how I could realize this would be greatly appreciated .
Thanks,
Stefan
This works for me, and it isn't retricted to a known set of template
parameters. But it doesn't pass the member function to be called to the
call method. I wasn't sure if that was part of your requirements or not.
john
#include <iostream>
class B;
class Base
{
public:
virtual void call(B* b) = 0;
};
class B
{
public:
void x(Base *pSomePtr)
{
pSomePtr->call(this);
};
template <class T1,class T2>
void y()
{
std::cout << typeid(T1).name() << ' ' << typeid(T2).name() << '\n';
};
};
template <class T1, class T2>
class A : public Base
{
public:
void call(B* b)
{
b->y<T1, T2>();
}
};
int main()
{
A<int, double> a;
B b;
b.x(&a);
}
Thanks for your reply. Sorry I forgot to mention this, but
unfortunately it is one of the key requirements to specify the member
function to be called, so you can do somthing like this:
class B
{
public:
void x(Base *pSomePtr, Base *pSomeOtherPtr)
{
pSomePtr->call(this,&B::dosomething);
pSomePtr->call(this,&B::dosomethingelse);
pSomeOtherPtr->call(this,&B::doanotherthing);
};
template <class T1,class T2>
void dosomething()
{
std::cout << typeid(T1).name() << ' ' <<
typeid(T2).name() << '\n';
};
template <class T1,class T2>
void dosomethingelse()
{
std::cout << typeid(T1).name() << ' ' <<
typeid(T2).name() << '\n';
};
template <class T1,class T2>
void doanotherthing()
{
std::cout << typeid(T1).name() << ' ' <<
typeid(T2).name() << '\n';
};
};
If it wasn't for that, I guess your solution would be ideal. The
problem with what I want is - of course - that it's impossible using
member function pointers. So I'm looking for something that would
provide a similarly nice syntax.
--Stefan
This is the best I could do with the existing example
code. I could not figure out how to deal with function
template-ids since I am not sure if they can be easily
substituted for class template-ids. Thus, I had to
manually, instantiate the member function down below.
BTW, based on your real specs, I will post a different
idea for you. This one I think does not fit well BUT
you can learn a lot from this, I believe.
------------------------------------------------------
#include <boost/function.hpp>
class B;
class Base
{
public:
typedef boost::function<void (B*)> Functor;
virtual void call( B *b, Functor func ) =0;
virtual void getFunctor() = 0;
};
// had to move the definition of B up due to dependency.
class B
{
public:
void x();
template<class T1, class T2>
void y()
{
}
template<class T1, class T2>
void z()
{
}
};
template <class T1,class T2>
class A : public Base
{
public:
virtual void call( B *b, boost::function<int (B*)> func )
{
// apply functor
func( b );
}
}
inline void B::x()
{
Base *pSomePtr = new A<int, float>();
pSomePtr->call( this, &B::y<int,float> );
pSomePtr->call( this, &B::z<int,float> );
};