Preciso passar ponteiros para funções membro como parâmetros para outras funções. Eu costumo std::mem_fn
envolvê-los em objetos de função.
Às vezes, as funções membro têm sobrecargas. Aprendi duas formas de sintaxe para desambiguar as sobrecargas:
- Para desambiguar funções de membro de modelo, eu uso
T::template member<template-args>
a expressão ponteiro-para-membro. - Para desambiguar funções de membro não-modelo quando todas as sobrecargas são funções de membro não-modelo, passo o tipo de função como argumento de modelo explícito para
mem_fn
:mem_fn<return-type(args-types)>(pointer-to-member-expression)
.
Mas qual sintaxe deve ser usada para desambiguar uma função membro não template quando algumas sobrecargas são funções membro template? Meu palpite direto não compila:
#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;
}
Veja também: https://godbolt.org/z/39dd569cK
A propósito, eu uso C++20, mas vejo os mesmos erros também em C++11.
Você pode fornecer todos os parâmetros do modelo:
Demonstração