c++templatesoverloadingfunction-pointersdisambiguation

How do I disambiguate a member function from a member function template


I need to pass pointers to member functions as parameters to other functions. I use std::mem_fn to wrap those in function objects.

Sometimes the member functions have overloads. I learned two syntax forms to disambiguate the overloads:

But what syntax should be used to disambiguate a non-template member function when some overloads are template member functions? My straightforward guess does not compile:

#include <iostream>   // cout
#include <functional> // mem_fn

struct C {
    void f() { std::cout << "f()\n"; }
    void f(int) { std::cout << "f(int)\n"; }

    template <class T>
    void g(T) { std::cout << "g(T)\n"; }
    template <class T1, class T2>
    void g(T1) { std::cout << "g<T1,T2>(T1)\n"; }

    template <class T>
    void h(T) { std::cout << "h(T)\n"; }
    void h(int) { std::cout << "h(int)\n"; }
};

int main() {
    C c;
    // non-template member function vs non-template member function
    std::mem_fn<void()>(&C::f)(c);
    std::mem_fn<void(int)>(&C::f)(c, 1);

    // template member function vs template member function
    std::mem_fn(&C::template g<int>)(c, 1);
    std::mem_fn(&C::template g<int, int>)(c, 1);

    // non-template member function vs template member function
    std::mem_fn(&C::template h<int>)(c, 1);
    // gcc: error: no matching function for call to 'mem_fn<void(int)>(<unresolved overloaded function type>)'
    // clang: error: no matching function for call to 'mem_fn'
    // std::mem_fn<void(int)>(&C::h)(c, 1);

    return 0;
}

See also: https://godbolt.org/z/39dd569cK

FWIW I use C++20 but see the same errors also in C++11.


Solution

  • You might provide all template parameters:

    std::mem_fn<void(int), C>(&C::h)(c, 1);
    

    Demo