Class templates and STL Containers
Hi - I have some design problem. I made my Template Class:
Code:
class CParam : CParamI {
public:
T operator=( T val ) {
value = val;
return value;
}
T getValue() {
return value;
}
virtual CString makeString();
private:
T value;
};
implementation of "makeString" function depends on T type <float>, <int>, <COLEDatetime>:
Code:
template<> CString CParam<float>::makeString() {
CString tmp;
tmp.Format( _T("%0.2f"), value );
return tmp;
}
template<> CString CParam<int>::makeString() {
CString tmp;
tmp.Format( _T("%0i"), value );
return tmp;
}
template<> CString CParam<COleDateTime>::makeString() {
return value.Format(dateFormat);
}
To put my CParam objects into std::map I made CParamI interface class with only one method: "makeString". I put all my CParam<T> objects overrided to CParamI into std::map<BYTE,CParamI>. Now, what should I do if I want to update values of some objects in my map (ie. add anything to CParam<float>) ? Is there any way to recognise type of CParam<T> ? Or maybe is there any way to make map from template class objects without using additional interface class ?
Re: Class templates and STL Containers
There's a few problems here. First, I don't think that virtual and template are compatible, so you will need to remove the virtual declaration in the CParam declaration. (It should still work so long as the function is declared virtual in CParamI.)
Second, your map needs to have a value type which is a pointer or smart pointer to CParamI. You cannot store these objects by value or you will end up with "slicing". To be sure you don't accidentally slice your objects, you can make CParamI abstract by declaring makeString() as pure virtual.
Third, if you have a limited number of possible types you expect to handle, you should consider whether a boost::variant is a more appropriate way of approaching the issue.
Fourth, the more common way to handle converting multiple different types into a string is by overloading operator<< for use with an ostringstream. This will give you a std::string rather than a CString, but that's easily convertible if you like.