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