Из-за чего function wrapper с ссылкой в сигнатуре может принимать pointer to member function?

Ссылка скопирована
1 ответ

По вводным: к примеру стандартный function wrapper - std::function.
Нужно понять: при сигнатуре void(T&, ars...) может принимать &T::Method. Разве у всех методов не указатель первый аргумент?

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
WordPress-редакция Ответ

В C++ pointer to member function — это отдельный тип, не равный обычному указателю на функцию. Если ваш function wrapper с ссылкой в сигнатуре его принимает, вероятно, используется шаблонная обёртка, которая принимает любой callable и внутри применяет std::invoke. Начиная с C++17, std::invoke как раз умеет вызывать member function pointer с объектом или ссылкой на объект.

Например, указатель на метод выглядит так:

struct A {
    void f(int);
};
 
void (A::*pmf)(int) = &A::f;

struct A { void f(int); }; void (A::*pmf)(int) = &A::f;

Вызвать его обычным синтаксисом нельзя как свободную функцию. Нужно либо:

A a;
(a.*pmf)(10);

A a; (a.*pmf)(10);

либо через std::invoke:

std::invoke(pmf, a, 10);

std::invoke(pmf, a, 10);

Если wrapper написан как универсальный callable, он может принимать и lambda, и functor, и function pointer, и pointer to member function. Особенно если в сигнатуре есть forwarding reference вида F&&. Название “ссылка в сигнатуре” здесь может сбивать с толку: это не значит, что принимается только ссылка на функцию. Шаблон может принять любой подходящий тип.

Проверьте, где именно происходит ограничение callable-типа. Если используется std::is_invocable, std::function, std::bind или std::invoke_result, member function pointer может считаться валидным, если вместе с ним передаётся объект.

Итог: pointer to member function принимается не потому, что он “обычная функция”, а потому что обёртка, скорее всего, шаблонная и совместима с std::invoke. Если хотите запретить такие типы, нужно явно ограничить шаблон traits-проверкой, например исключить std::is_member_function_pointer_v<T>.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно