This article lists all the different categories of pointers. I have tested the explicit conversion of different types of pointers to const void*
in the following snippet (live):
#include <print>
int var {};
void foo()
{
}
struct Bar
{
char mem;
void func()
{
}
};
Bar b {};
int main()
{
// nullptr
std::println( "{}", static_cast<const void*>( nullptr ) );
// pointer to object
std::println( "{}", static_cast<const void*>( &var ) );
// pointer to function
std::println( "{}", reinterpret_cast<const void*>( &foo ) );
// pointer to member variable
std::println( "{}", static_cast<const void*>( &Bar::mem ) ); // doesn't compile
std::println( "{}", static_cast<const void*>( &(b.mem) ) );
std::println( "{}", static_cast<const void*>( &(b.*(&Bar::mem)) ) );
// pointer to member function
std::println( "{}", reinterpret_cast<const void*>( &Bar::func ) ); // compiles with a warning
std::println( "{}", reinterpret_cast<const void*>( &(b.func) ) ); // doesn't compile
std::println( "{}", reinterpret_cast<const void*>( &(b.*(&Bar::func)) ) ); // doesn't compile
// Did I miss any other category?
}
Now I have a few questions:
static_cast<const void*>( &Bar::mem ) );
does not compile (since &(b.*(&Bar::mem))
does). The compiler says:error: invalid 'static_cast' from type 'char Bar::*' to type 'const void*'
ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&Bar::func'
A pointer to member is different from other pointers. Its not bound to a specific instance, but its rather an offset into a class. Given an instance you can use a pointer to member to get the member. Casting it to void*
is of no great use, hence C++ does not allow it. Generally C++ is less permissive than C concering casts to void*
. Hence, static_cast<const void*>( &Bar::mem ) );
does not compile.
On the other hand (b.*(&Bar::mem)
uses the instance and the pointer to member to get a reference to the member mem
of b
. And &(b.*(&Bar::mem)
is just the same as &(b.mem)
. Its a pointer to b.mem
, a char*
. You can cast char*
to void*
.
(2) and (3) is just about how the syntax is defined.