Вызов функтора с определенной функцией из набора перегрузки - PullRequest
0 голосов
/ 14 января 2019

Контекст

В контексте математики я бы хотел определить функторы, работающие с функциями <cmath>. Для целей этого вопроса мы будем использовать std::invoke в качестве нашего функтора.

Это плохо сформировано (живое демо) :

std::invoke(std::sin, 0.0);

(g ++ - 8.1) ошибка: нет соответствующей функции для вызова 'invoke (<неразрешенный тип перегруженной функции>, double)'

Действительно, std::sin - это набор перегрузки, и компилятору не хватает информации о типе для выбора одной из этих функций.

Вопрос * * 1023 Как я могу назвать конкретную функцию из набора перегрузки? Чем мы можем заменить LEFT и RIGHT, чтобы следующее было правильно сформировано и соответствовало ожидаемому (скажем, выберите double std::sin(double))? #include <functional> #include <cmath> int main() { (void) std::invoke(LEFT std::sin RIGHT, 0.0); } Если это невозможно, есть ли способ определить функтор, чтобы он учитывал перегрузку?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Самый простой способ, который я знаю, это использовать лямбду для включения поиска перегрузки

std::invoke([](auto val){return std::sin(val);}, 0.0);

Позволит вам передать любое значение в invoke, и тогда лямбда-тело будет обрабатывать фактический вызов, и тогда придет разрешение перегрузки.

Вы можете использовать макрос, чтобы абстрагировать лямбда-тело от вызова на invoke, используя что-то вроде

#define FUNCTORIZE(func) [](auto&&... val) noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) {return func(std::forward<decltype(val)>(val)...);}
//...
std::invoke(FUNCTORIZE(std::sin), 0.0);
0 голосов
/ 14 января 2019

Как я могу назвать конкретную функцию из набора перегрузки?

static_cast. Э.Г.

std::invoke(static_cast< double(*)(double) >( &std::sin ), 0.0);

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

std::invoke([](auto x){ return std::sin(x); }, 0.0);

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

Нормативный справочник для использования static_cast: здесь .

...