std :: function против стандартных функций - PullRequest
0 голосов
/ 14 января 2019

Я играл с указателями на функции против std :: function и столкнулся со следующей проблемой.

Давайте рассмотрим следующий код:

#include <cmath>
#include <functional>

// g++ -std=c++17 SF.C -o SF
// clang++ -std=c++17 SF.C -o SF

int main()
{
    typedef double (*TpFunctionPointer)(double) ;

    TpFunctionPointer pf1 = sin;                     // o.k.
    TpFunctionPointer pf2 = std::sin;                // o.k
    TpFunctionPointer pf3 = std::riemann_zeta;       // o.k

    std::function< double(double) > sf1( sin );                // o.k
    std::function< double(double) > sf2( std::sin );           // fails
    std::function< double(double) > sf3( std::riemann_zeta );  // fails
}

Компиляция с g++ v8.2 или clang v7.0 отлично работает для указателя функции pf1, pf2, pf3 и для sf1. Однако для sf2 и sf3 я получаю довольно длинные сообщения об ошибках, например ::

SF.C:17:47: error: no matching function for call to ‘std::function<double(double)>::function(<unresolved overloaded function type>)’
  std::function< double(double)> sf2( std::sin );           // fails

Это предполагаемое поведение?
Разве sf2 и sf3 не должны быть в порядке?

1 Ответ

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

Есть несколько перегрузок <cmath> std::sin (есть версия шаблона в <complex>, но это не то, что вам нужно), и компилятор не ' не знаю, какой вы хотите, несмотря на тот факт, что только один из них будет успешно привязан к вашему типу std::function В этом смысле C ++ не выполняет поиск в обратном направлении & hellip;

& hellip; кроме случаев, когда это происходит! Исключение составляет static_cast для указателя на функцию типа , что вам здесь и нужно:

std::function<double(double)> sf2(static_cast<double(*)(double)>(&std::sin));

Пример этого есть на странице документации по static_cast cppreference .

Некоторые потенциальные улучшения по сравнению с этим общим решением (спасибо Натану и MSalters):

std::function<double(double)> sf2(static_cast<TpFunctionPointer>(&std::sin))

или

std::function<double(double)> sf2([](double val){ return std::sin(val); });
...