Как получить указатель на функцию-член, если существует в шаблоне - PullRequest
1 голос
/ 07 ноября 2019

Чтобы получить указатель на функцию-член класса, мы делаем следующее:

return_type (Class::*varName)(paramType1, paramTypeN) = &Class::functionName; 

«Имя функции» должно быть известно заранее.

Дело в том, что я не знаю (мыне должно на самом деле) заботиться об имени функции, есть ли способ, которым я мог бы проверить существование "указателя на функцию-член", если он не равен нулю, я вызываю его.

Я хотел бы сделать этов моем классе шаблонов.

Если объект параметра шаблона имеет функцию-член, которая соответствует ожидаемой подписи, я вызываю эту функцию.

Код не является допустимым кодом C ++, но даетвы намек на то, что я ищу.

template< typename T >
class MyTemplateClass {

    void myFunction(T& object) {

        if constexpr( exists_in_class< T, void (T::*)(const int&, const int&) >::value ) {

                call_member_function_pointer< 
                    T, 
                    void (T::*)(const int&, const int&) >( object, 1, 2 );

          }
    }
};

Если это невозможно, потому что у вас может быть много функций с разными именами, но с одинаковой точной сигнатурой (прототип). Можно ли найти способ передать имя функции следующим образом:

template< typename T >
class MyTemplateClass {

    void myFunction(T& object) {

        if constexpr( exists_in_class< T, void (T::*)(const int&, const int&), FunctionNameIExpect >::value ) {

                call_member_function_pointer< 
                    T, 
                    void (T::*)(const int&, const int&),
                    FunctionNameIExpect >( object, 1, 2 );

          }
    }
};

1 Ответ

0 голосов
/ 07 ноября 2019

С std :: эксперимент :: :: is_detected , вы можете сделать:


template<class T>
using has_my_function_name_t = decltype(&T::my_function_name);

template< typename T >
class MyTemplateClass
{
public:
    void myFunction(T& object)
    {
        if constexpr(std::experimental::is_detected_exact<void (T::*)(const int&, const int&),
                                                          has_my_function_name_t, T>::value) {
            object.my_function_name(1, 2);
        }
    }
};

Демо

Если вы более разрешены вразрешенная подпись (Ret (T::*)(int, int) /*const*/), возможно использование std::is_invocable.

...