While experimenting with auto
and function pointers I notice a strange behavior
class Test
{
public:
void Func(){}
};
static constexpr const auto member_ptr1{ &Test::Func }; // compile fine
static constexpr const void(Test::*member_ptr2)(void) { &Test::Func }; // ERROR : cannot convert from void(Test::*)(void) to const void(Test::* const)(void)
I understand that, in the case of member_ptr2
, the compiler complain about not finding a function with the signature const void Func()
, but it should trigger the same error for member_ptr1
.
So what does the compiler do under the hood with member_ptr2
?
Bonus question : what does const
means right after Test::*
? I notice that in the compiler output.
Second bonus question : When using function pointers is there any difference between constexpr const auto member_ptr1{...}
and constexpr auto member_ptr1{...}
?
This
static constexpr const auto member_ptr1{ &Test::Func };
declares a constant pointer to a member function. That is the pointer itself that is constant.
This record is equivalent to
static constexpr void(Test::* const member_ptr2)(void) { &Test::Func };
Here is a demonstrative program.
#include <iostream>
#include <iomanip>
#include <type_traits>
class Test
{
public:
void Func(){}
};
static constexpr const auto member_ptr1{ &Test::Func }; // compile fine
static constexpr void(Test::* const member_ptr2)(void) { &Test::Func };
int main()
{
std::cout << std::boolalpha
<< std::is_same<decltype( member_ptr1 ), decltype( member_ptr2 )>::value
<< '\n';
return 0;
}
Its output is
true
And here is another simplified demonstrative program.
#include <iostream>
int main()
{
int x = 10;
const auto p = &x;
*p = 20;
std::cout << "x = " << x << '\n';
return 0;
}
The program output is
x = 20
That is the pointer p
has the type int * const
not the type const int *
.
The type in place of the placeholder auto
at first is deduced from the used initializer and then the qualifier const is applied to the deduced type.