This is impossible. The types in C++ are (mostly) a compile-time property. At runtime, types are unknown (they are erased).
However, RTTI exist, notably for instances of some class
containing virtual methods.
There is no possible trick in general. You could redesign your program by having some kind of variant type, or by having a common root class from which all your objects inherit, etc etc, or by using union types (better have your own discriminated unions).
Put it another way: when the compiler see a void*
pointer, it does not even know the size of the data pointed by that pointer.
Future C++ standards might propose some std::any container.
Maybe you could have something like a cheap discriminated union class like
class Int_or_String {
const bool isint;
union {
int n;
std::string s;
};
Int_or_String(const int i) : isint(true), n(i) {};
Int_or_String(const std::string &st): isint(false), s(st) {};
~Int_or_String() { if (isint) n=0; else
/*not sure*/ s.std::string::~std::string(); };
// much more is missing
};
I'm not even sure of the syntax to explicitly destroy a union member.
See e.g. this question on calling destructors explicitly
Perhaps the Qt object model might inspire you. Look also into its QVariant
The usual way is to define a root class in your program and adopt the convention that all your objects are inheriting this root class (or even that all your meaningful data are in objects derived from that root class). This requires a redesign of the whole thing.
So you would decide that your root class is e.g
class Root {
public:
virtual void out(std::ostream&s) =0;
virtual ~Root() =0;
/// other common methods
};
static inline std::ostream& operator << (std::ostream&o, const Root &r)
{ r.out(o); return o; }
class Integer : public Root {
const int num;
public:
Integer(int n) : Root(), num(n) {};
void out (std::ostream &o) { o << num ; };
/// etc...
}; // end class Num
class String : public Root {
const std::string str;
public:
String(const std::string& s) : Root(), str(s) {};
void out (std::ostream &o) { o << str ; };
/// etc...
}; // end class String