Matthias said:
This looks like a compile time version of dynamic_cast.
The problem here is that I need to pass elp into another templated
function. This means I would need to do something like this in the
Derived implementation:
setParam(std::string s, envelop elp)
{
createPythonObject( elp.query_object() );
This won't compile because I have to do something like
createPythonObject( elp.query_object<Type>() ); The createPythonObject
template has lots of different specializations depending on the type of
the class that was wrapped by elp.
Ok, here's the trick: bring every essential operation up to
objectwrapper_base class. For example:
class objectwrapper_base // runtime support for type query
{
public:
virtual const void* query_object(std::type_info) const = 0;
virtual ~objectwrapper_base(){}
// the following member function is newly added:
virtual void createPythonObject(void);
};
Now in the corresponding objectwrapper template, implement the member:
template <typename T> // compile time type information build up
class objectwrapper: public objectwrapper_base
{
const T* ptr;
public:
objectwrapper(const T& t){ptr = &t;}
const void* query_object(std::type_info ti) const{
if (ti == typeid(T))
return static_cast<const void*>(ptr);
return 0;
}
// newly implemented function:
void createPythonObject(void){
::createPythonObject(*ptr);
}
};
Finally, you need to wrap these in the envelop class:
class envelop // a simple class to wrap the above up into one
{
std::auto_ptr<
objectwrapper_base> wrapper;
public:
template <typename T>
envelop(const T& obj):
wrapper(new objectwrapper<T>(obj))
{}
template <typename T> // just a wrapper function
const T* query_object(void) const{
return static_cast<const T*>(
wrapper->query_object(typeid(T)));
}
// newly added function
void createPythonObject(void){
wrapper->createPythonObject();
}
};
Now all you need in SetParam is hence:
setParam(std::string s, envelop elp){
// createPythonObject( elp.query_object() );
elp.createPythonObject();
// ...
}
Regards,
Ben