В моей программе я нахожу ситуацию, когда я хочу UserClass
, что
- - это контейнер, который может содержать гетерогенные типы
- может вызывать функции-члены удерживаемых объектов.
Набор поддерживаемых типов ограничен и известен во время компиляции.На самом деле, все типы - это просто разные template
специализации.
Этот код иллюстрирует ситуацию:
class ArrayBase { /*etc.*/ }; // definition not changeable
template <class T>
class TypedArray : public ArrayBase // definition not changeable
{
/*more functionality needed by SpecializedArray.*/
}
template<class T>
class SpecializedArray : public TypedArray<T>
{
public:
void newFunctionalityMember() { /*etc.*/ };
};
class UserClass
{
addArray( arrayElmentTypeEnum_t t)
{
switch(t) {
case float_id:
_elementArrays.push_back( new SpecializedArray<float>() );
break;
case double_id:
_elementArrays.push_back( new SpecializedArray<double>() );
break;
default:
break;
}
void doSomethingWithASpecializedArray(int num)
{
// using _elementArrays[num], call the correct newFunctionalityMember()
}
private:
std::vetor<storagePtr_t> _elementArrays;
}
Без некоторой просьбы я не могу изменить ArrayBase
или TypedArray
.Я оставил тип storagePtr_t
неопределенным, так как тип должен быть ключевым в моем вопросе.
Я могу придумать одно решение, показанное ниже.Но какая боль!Это много кода, чтобы иметь где-нибудь в UserClass
, что мне нужно для доступа к элементам элемента. Есть ли лучший способ?
библиотека повышения - это честная игра.
моя техника:
storagePtr_t
is ArrayBase*
, arrayElmentTypeEnum_t
будет std::type_info*
UserClass::doSomethingWithASpecializedArray(int num)
{
// these two both uniquely identified by num.
storagePtr_t * bptr = _elementArrays[num];
arrayElmentTypeEnum_t typekey = ...
if (typekey == &typeid(SpecializedArray<float>) ) {
D<float> * dptr = static_cast<SpecializedArray<float>*>(bptr);
dptr->newFunctionalityMember();
} else if (typekey == &typeid(SpecializedArray<double>) ) {
D<float> * dptr = static_cast<SpecializedArray<double>*>(bptr);
dptr->newFunctionalityMember();
} else if (typekey == &typeid(SpecializedArray<int>) ) {
D<float> * dptr = static_cast<SpecializedArray<int>*>(bptr);
dptr->newFunctionalityMember();
}
}