Как сделать универсальный шаблон, для передачи указателей на методы

Я хочу сделать шаблон функции, в который я смогу передавать указатели на методы, в том числе и методы класса.

Но так нельзя:

void g_fnc() {};

class tst {
public:
    void fnc() {};
};
template<typename Func>
void SearchFunc(Func * p_func){}

int main()
{
    SearchFunc(&g_fnc);//OK
    SearchFunc(&tst::fnc);//Отсутствуют экземпляры шаблона
}

Можно ли сделать шаблон, который будет подходить и под методы-члены классов?


Ответы (1 шт):

Автор решения: Chorkov

Если вы хотите обрабатывать функции-члены класса отдельной (частичной) специализацией шаблона:

// Эта специализация будет обрабатывать как указатели на функции, так и указатели на данные
template<typename Func>
void SearchFunc(Func * ptr);

// Это именно указатель на функцию
template<typename Result, typename ... Args >
void SearchFunc(Result  (*ptr)(Args... ) );


// Это указатель на член класса (даные)
template<typename DataType, typename HolderTye >
void SearchFunc(DataType  HolderTye::*ptr );

// Это указатель на функцию - член класса 
template<typename Result, typename HolderTye, typename ... Args >
void SearchFunc(Result  (HolderTye::*ptr) (Args... ) );

Однако, никаких гарантий, что передаваемый указатель - суть адрес кода в памяти стандарт не дает. Указатель на функцию-член класса, не связан ограничениями обратной совместимости с С, поэтому у компилятора развязаны руки.

Более того, он может не совпадать с указателем на данные, даже по размеру: https://godbolt.org/z/a6WKz1zf1

→ Ссылка