I\'m looking at std:variant
/std::visit
doc here: http://en.cppreference.com/w/cpp/utility/variant/visit and also googled a lot trying to understand
What I think, is that under the hood std::visit
builds an array of function pointers (at compile time) which consists of instantiated function pointers for each type. The variant stores a run-time type index i
(intgeral number) which makes it possible to select the right i
-th function pointer and inject the value.
You might wonder how can we store function pointers with different argument types in a compile time array? -> This is done with type-erasure (I think), which means
one stores functions with e.g. a void*
argument, e.g. &A<T>::call
:
template<typename T>
struct A
{
static call(void*p) { otherFunction(static_cast<T*>(p)); }
}
where each call
dispatches to the correct function otherFunction
with the argument (this is your lambda at the end).
Type erasure means the function auto f = &A<T>::call
has no more notion of the type T
and has signature void(*)(void*)
.
std::variant
is really complicated and quite sophisticated as lots of powerful fancy metaprogramming tricks come into play. This answer might only cover the tip of the iceberg :-)