c++templatesfunction-pointersmember-functionsexplicit-instantiation

How to take address of templated member function instance in C++?


I was trying to take address of templated member function instance. For some reason, it is not working. Here is minimal reproducible example:

class X {
    public:

    template<bool B>
    inline void f() {}

    const decltype(f<true>)* truef = f<true>;
    const decltype(f<false>)* falsef = f<false>;
};

The above code is giving the following error:

<source>:7:27: error: 'decltype' cannot resolve address of overloaded function
    7 |     const decltype(f<true>)* truef = f<true>;
      |                           ^
<source>:8:28: error: 'decltype' cannot resolve address of overloaded function
    8 |     const decltype(f<false>)* falsef = f<false>;
      |                            ^
<source>:7:38: error: cannot resolve overloaded function 'f' based on conversion to type 'const int*'
    7 |     const decltype(f<true>)* truef = f<true>;
      |                                      ^~~~~~~
<source>:8:40: error: cannot resolve overloaded function 'f' based on conversion to type 'const int*'
    8 |     const decltype(f<false>)* falsef = f<false>;

But the same code works if f wasn't a member function:


template<bool B>
inline void f() {}

constexpr decltype(f<true>)* truef = f<true>;
constexpr decltype(f<false>)* falsef = f<false>;

So, how to take address of templated member function instance in C++?


Solution

  • The correct syntax to get a pointer to a member function would be: &classname::membername so that the program should be modified to as shown below.

    Basically, pointer to member functions distinct from ordinary pointers(like pointer to normal functions).

    class X { 
        public:
    
        template<bool B>
        inline void f() {}
    //-----------------vvvv------------------------------->changed syntax here
        const decltype(&X::f<true>) truef = &X::f<true>;
        const decltype(&X::f<false>) falsef = &X::f<false>;
    };
    

    Demo