views:

151

answers:

6

Hi!

the title probably is misleading, but i didn't really know how to name it.

let's say I have the following structs

template <typename T>
struct SillyBase{
   void doFunnyStuff(vector<T> vec){
        dummyField = T();
        for(int i=0; i<10; i++)
            vec.push_back(dummyField++);
    }
    T dummyField;
 };

struct A : public SillyBase<char>{};

struct B : public SillyBase<float>{};

now let's further assume i have a pointer

ISillyBase* ptr;

which is pointing to an object of a DECENDANT class (A or B) of SillyBase - however, i DON'T KNOW which one (i just know it's either A or B);

Is there ANY way for me to call doFunnyStuff() ?

maybe something like:

vector<dynamic_generic_type_of(ptr)> vec;
ptr->doFunnyStuff(vec);

thanks!

A: 

EDIT: even with ISillyBase, there is no such thing as virtual template members so you won't be able to define one that takes vector<T> parameter.


Well in your example, there is no such non template type as SillyBase hence you cannot declare SillyBase* ptr;

And in the end I don't really see what you're trying to achieve :/

Gregory Pakosz
+1  A: 

In your example you can't have SillyBase* because SillyBase is defined as

template <typename T> struct SillyBase {...}

So you need to provide type ...

Another problem is that you pass a copy of vector<T> into doFunnyStuff() which you then populate ... that does not seems right because when the method returns you lose your vec, was it supposed to be reference vector<T>& ?

stefanB
you could have in ISillyBase a virtual doFunnyStuff but the problem is that it needs to know the type of parameter ... so it can't be virtual ... maybe explain what you are trying to achieve and there might be easier solution.
stefanB
ok got it - it's not gonna work that way :)
genesys
A: 

The SillyBase *ptr; shouldn't even compile. Without a template parameter list, SillyBase isn't a type, so attempting to use it in a context that requires a type should fail.

Since you can't create the pointer in the first place, there's no real answer to how to dereference it.

Jerry Coffin
A: 

These are actually two absolutely different classes. There is no way to call function by name in classes that have met 100 years ago on their aunt wedding. You have to redesign the solution to include some base class for your template classes like

class SillyBaseBase
{
    public:
        void function doFunnyFunnyStuff(SillyBase<char> *)
        {
            SillyBase<char>::doFunnyStuff();
        }

        void function doFunnyFunnyStuff(SillyBase<float> *)
        {
            SillyBase<float>::doFunnyStuff();
        }

}
alemjerus
A: 

I think what you're looking for is the built in dynamic_cast template function. It dynamically determines the type of a data structure and returns null if it is not an instantiation. The syntax is

dynamic_cast<the_template_definition>(the_template_instantiation)

The one important catch is that the template classes must derive from a common virtual class. So to do what you want, you can use the following code:

#include <stdio.h>
class Top /* The parent class */ {
public: 
virtual ~Top() {}; // You need one base virtual function in the base class
};

template <typename T> class SillyBase : public Top {
   void doFunnyStuff(T dummyVar){
        dummyField  = dummyField + dummyVar;
    }
    T dummyField;
 };

class A : public SillyBase<char>{};
class B : public SillyBase<float>{};

int main(){
   A a;
   Top *ptr = (Top*)(&a);
   if(dynamic_cast<A*>(ptr) != NULL)
      printf("ptr is of type A*\n");
   if(dynamic_cast<B*>(ptr) != NULL)
      printf("ptr is of type B*\n");
   return 0;
}

The output of the program will be:

ptr is of type A*
speedplane
A: 

I would probably go with the dynamic_cast keyword. Although you would run into a problem when you declare the vector. It would have to be of type SillyBase. The problem with this is that this requires the use of template arguments, which would be unkown and impossible to get. To remedy this problem in the past, I've just put the vector in the Base class of type base, and then providing a functions to modify it. The inheireted class would provide a variable of the same name of the vector's in the base class. The inheireted class, inheiriting the base class's functions would hopefully fill the correct vector. I don't know if this is a good idea or a bad idea, but it's the way I attempted to overcome this problem within my projects.

Jeff