Reputation: 61
How to check what is a runtime type under a void* pointer. For example, how to write such a function:
void f(void *p) {
// check if *p is an int or a vector
}
Modern C++ versions (14, 17) are welcome. Future versions are also interesting as an information for the future.
There is no base class nor common virtual methods and simple types are allowed, so How to determine actual object type at runtime in C++; is not exactly relevant.
EDIT:
OK, in certain cases, if the caller knows the real type of the pointer, overloads could be a solution for the simplified example above. But what about something slightly more complex:
using ::std::vector;
void f(vector<void*> v) {
// check if particular *v[i]'s are ints or vectors
}
Also void* in a function declaration was not my idea.
Upvotes: 1
Views: 311
Reputation: 4201
Forget about void*
. It is a one way ticket; once you step in, there is no way back and all static type info is gone for good.
If the set of used types is unbound, go for std::any
(c++17 or boost). It may trigger dynamic allocation, but also has small value optimization:
http://en.cppreference.com/w/cpp/utility/any
But if the set of used types is countable and bound, consider std::variant
(c++14 or boost). You may investigate static visitor pattern:
http://en.cppreference.com/w/cpp/utility/variant
Upvotes: 0
Reputation: 93264
This is not possible for primitive types, and honestly it is a terrible idea. void*
is just an address to anything - there's no information here that can be used to deduce what the actual type of the pointee is.
In practice, one of the reasons why this can be done for polymorphic types is because run-time type information can be stored in the vtable. (Note that the Standard doesn't require the use of a vtable, but it's the most common implementation.)
Upvotes: 0
Reputation: 122228
It is not really clear, why you have a void*
in the first place. Once you have a void*
any information on the actual type is lost and the function you'd like to write is not possible in C++. If you want to call the same method with either a pointer to int
or pointer to std::vector
you would rather use overloads:
void f(int* p) {
std::cout << "f called with pointer to int";
}
template <typename T>
void f(std::vector<T>* p) {
std::cout << "f called with pointer to vector";
}
Upvotes: 3