Not too familiar with boost::any, since it requires you to know the type you are storing to retrieve it.
Printable View
Not too familiar with boost::any, since it requires you to know the type you are storing to retrieve it.
Wait, what exactly are you trying to do? Without knowing that we are all just guessing what is the best tool for the job.
Perhaps virtual classes are a good solution for this type of job?
The list stores base classes while exposing virtual functions which the derived classes override and implement.
Otherwise I figure you're going to have to circumvent the whole type system by checking for type and casting it appropriately, which never is a good idea.
So, in your original model, you wanted to store objects of different instances of the class template in the same std::list, right? What is the motivation for a class template instead of a "normal" Variable class, say a class hierarchy?Quote:
Originally Posted by chadsxe
Well the "Variable class" obviously is going to have to store a few different types of variables. Instead of declaring a type of each variable that I will be using in my simple scripting language in the "Variable class", I figured the templated option would be more efficent. The problem is the ScriptingManager class store variable(s) inside of a list.
Hmmm. Templates and virtual functions does not always play well with each other...
As in you are "borrowing" the built-in types of C++? I am not sure how that works with your scripting language, but a possible solution could be to have a VariableType abstract base class, then have a ConcreteVariableType class template inherit from it, since a variable has-a type:Quote:
Originally Posted by chadsxe
As such, you would have a std::list<Variable>, but each Variable object would have a (smart) pointer to a VariableType, which could point to a ConcreteVariableType<int>, ConcreteVariableType<double>, etc.Code:class VariableType
{
public:
virtual ~VariableType() {}
// ...
};
template<typename T>
class ConcreteVariableType : public VariableType
{
// ...
};
Then again, if your scripting language is so simple, wouldn't it be quite easy to just list all the possible types that the variables have?
Edit: And by the by, the suggestion offered by LL is probably what you need.
They play together just fine so long as you don't treat template methods polymorphically.Quote:
Templates and virtual functions does not always play well with each other...
Some people expect the following code to print "b:1\nb:0\nd2:0\nd2:2\n" or some other unusual variation. You will not have problems so long as you don't expect the compiler to do magic things.Quote:
for instance? i haven't had any problems with it.
Soma
Code:#include <iostream>
struct b
{
template
<
unsigned int F
>
void t()
{
std::cout << "b:" << F << '\n';
}
virtual void t1()
{
t<0>();
}
virtual void t2()
{
t<0>();
}
};
struct d1: b
{
virtual void t1()
{
t<1>();
}
};
struct d2: b
{
template
<
unsigned int F
>
void t()
{
std::cout << "d2:" << F << '\n';
}
virtual void t2()
{
t<2>();
}
};
struct dc: d1, d2
{
};
int main()
{
dc t;
t.d1::t1();
t.d1::t2();
t.d2::t1();
t.d2::t2();
return(0);
}
The solution that laserlight suggests is one where such a problem may show up.
Virtual functions just won't work so well with inheritance in such an example, because it doesn't "offer" all the flexibility you might want or need.
Also consider the following example:
The first rTest.foo call will work as expected.Code:class Base
{
public:
virtual void foo(int) = 0 {}
};
template<typename T> class Derived: public Base
{
public:
virtual void foo(int) {}
virtual void foo(T) {}
};
int main()
{
Derived<double> Test;
Base& rTest = Test;
rTest.foo(10);
rTest.foo(1.0);
}
But the second one will not! It will simply truncate the double to int and call Derived::foo(int) instead of Derived::foo(double).
Which is why I said they don't play so well together.
If you want or need a template class, you might as well need to use the template type in the parameter list of some functions. And to call those functions, the base class needs to contain them, as well, as virtual functions, or you'll have to cast them to derived classes, which is wrong.
But since the base class isn't templated, it cannot represent those virtual functions in the derived class without overloading them all, and that almost kind of beats the purpose of a template class.
Um, but Elysia, your example is due to the fact that the foo() member function from Base takes an int. We could demonstrate this behaviour without templates:
EDIT:Code:class Base
{
public:
virtual void foo(int) = 0;
};
class Derived: public Base
{
public:
virtual void foo(int) {}
virtual void foo(double) {}
};
int main()
{
Derived Test;
Base& rTest = Test;
rTest.foo(10);
rTest.foo(1.0);
}
I can agree with your general sentiment, but it depends on the requirements and the design.Quote:
Originally Posted by Elysia
Which is my point.
There's just no way to make virtual functions that take T as a parameter without making the base a template class, as well.
And by doing that, we get the problem of what type is stored inside the list, which was the whole point of a non-template generic base class.
what is "wrong" with:
Code:template<typename T>void abstractClass::getter(T& t)
{
t= (static_cast<concreteClass<T>*>(this))->concreteClass<T>::memberOfTypeT;
}
template<typename T>void abstractClass::setter(T& t)
{
static_cast<concreteClass<T>*>(this))->concreteClass<T>::memberOfTypeT = t;
}
you should get a compile-time error if you mangle the types, no?