У вас не может быть такой вещи, как auto_cast
. C ++ нигде не хранит типы объектов, преобразованные в void*
. Вы должны знать этот тип самостоятельно, чтобы восстановить объект из void*
, поскольку это буквально просто указатель на некоторую область памяти без информации , что найти там.
Вы должны хранить некоторую информацию о типе рядом с void*
. Например, используя enum:
struct INPosition {
enum class ObjType { SET_X, SET_Y, MAP_Z };
INPosition(std::set<ObjX>::const_iterator pTMP) : element(&*pTMP), objType(ObjType::SET_X) {}
INPosition(std::set<ObjY>::const_iterator pTMP) : element(&*pTMP), objType(ObjType::SET_Y) {}
INPosition(std::map<ObjZ, Data>::const_iterator pTMP) : element(&*pTMP), objType(ObjType::MAP_Z) {}
private:
const void* element;
const ObjType objType;
};
Этого само по себе недостаточно, чтобы доставить вас туда, куда вы хотите, потому что вы не можете возвращать разные типы из одной и той же функции. Какой тип возврата вы ожидаете получить auto Iterator()
?
Урок здесь : используя void*
, вы явно побеждаете (или оставляете) систему типов C ++, но не можете написать никакой полезный код C ++ вне ее. Возвращение в систему типов из void*
требует некоторых усилий.
Вы могли бы реально сделать эту работу, используя (перегруженный) аргумент функтора для достижения чего-то полезного:
template<class OverloadedFunctor>
auto apply(OverloadedFunctor f)
{
switch (objType)
{
case ObjType::SET_X:
return f(*static_cast<const std::set<ObjX>::value_type*>(element));
case ObjType::SET_Y:
return f(*static_cast<const std::set<ObjY>::value_type*>(element));
case ObjType::MAP_Z:
return f(*static_cast<const std::map<ObjZ, Data>::value_type*>(element));
}
}
Тогда, если у вас был перегруженный функтор, который мог бы делать что-то полезное с каждым из этих типов, вы могли бы применить его так:
struct MyOverloadedFunctor
{
void operator()(const ObjX& x) const;
void operator()(const ObjY& y) const;
void operator()(const std::pair<ObjZ, Data>& zd) const;
};
std::set<ObjY> setY;
setY.emplace();
INPosition position(setY.begin());
MyOverloadedFunctor myOverloadedFunctorInstance;
position.apply(myOverloadedFunctorInstance); // will call the second overload.
Демо