Search code examples
c++function-pointerspointer-to-memberdecltypefunction-qualifier

Get address of const method


I would like to be able to form a pointer-to-member type knowing only the class itself and method name. Unfortunately I am not able to do so having a const and non-const method variants in my class.

Example code snippet:

struct A
{
    void method() {}
    void method() const {}
};

int main()
{
    decltype(&A::method) _;
}

I have also tried the following this but without much success either:

decltype(&(std::declval<const A>().method)) _;

Both approaches fail as decltype cannot resolve this due to ambiguity:

'decltype cannot resolve address of overloaded function'

How can I achieve this in some other way?


Solution

  • You can do it like this:

    struct A
    {
        void method() {
            cout << "Non const\n";    
        }
        void method() const {
            cout << "const function\n";
        }
    };
    
    int main()
    {
        typedef  void (A::*method_const)() const;
        method_const a = &A::method;     //address of const method
        
        typedef  void (A::*method_nonconst)();
        method_nonconst b = &A::method;  //address of non const method
        
        A var;
        std::invoke(a, var);
        std::invoke(b, var);
    }
    

    If you want to use decltype() to achieve the same thing, you first have to manually select the function you want using static_cast<>:

    int main()
    {
        //const
        decltype( static_cast <void (A::*)() const> (&A::method) ) a;
        //non const
        decltype( static_cast <void (A::*)()> (&A::method) ) b;
        
        a = &A::method;
        b = &A::method;
        
        A var;
        std::invoke(a, var);
        std::invoke(b, var);
    }
    

    Live on Coliru