What auto keyword does under the hood when used with function pointers?

Viewed 105

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{...} ?

1 Answers

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.

Related