vsoftco
vsoftco

Reputation: 56557

error passing a std::function vs a function pointer as a parameter

I have the following piece of code, in which I declare 2 functions that take a function as a parameter (one by using std::function, the other one by using a pointer to a function). The function taken as a parameter has to have the prototype std::complex<double>(const std::complex<double>&). An example of such a parameter is std::sqrt in C++11, see http://en.cppreference.com/w/cpp/numeric/complex/sqrt . Now, I have absolutely no clue why the function that takes a pointer-to-function works (i.e. g_of_ten), whereas the other one, that takes a std::function as a parameter, doesn't (i.e. f_of_ten). If I uncomment the line

//cout << f_of_ten(std::sqrt) << endl; // ERROR here!!!

I get the error

 error: no matching function for call to 'f_of_ten'
        cout << f_of_ten(std::sqrt) << endl; // ERROR here!!!
                ^~~~~~~~
    /Users/vlad/minimal.cpp:10:6: note: candidate function not viable: no overload of 'sqrt' matching 'std::function<cplx (const cplx &)> &' for 1st argument
    cplx f_of_ten(std::function<cplx(const cplx &)>& x)
     ^
    1 error generated.

I am completely puzzled why this is happening, I though that std::function is really a wrapper for all kinds of functors (INCLUDING standard functions). Any help is more than welcome! Below is the code:

#include <cmath>
#include <complex>
#include <functional>
#include <iostream>

using namespace std;

using cplx = complex<double>; // to save some typing

cplx f_of_ten(std::function<cplx(const cplx &)> x) // the problematic one
{
    return x(10);
}

cplx g_of_ten(cplx(*x)(const cplx &)) // this works
{
    return (*x)(10);
}


int main()
{
    //cout << f_of_ten(std::sqrt) << endl; // compile ERROR here!!!
    cout << g_of_ten(std::sqrt) << endl;
}

PS: I, of course, also tried cout << f_of_ten(&std::sqrt) << endl;, same story, compile time error.

@Yakk,

this works fine:

#include <cmath>
#include <complex>
#include <functional>
#include <iostream>
#include <valarray>

using cplx = std::complex<double>; // to save some typing

cplx f_of_ten(std::function<cplx(const cplx &)> x) // the problematic one
{
    return x(10);
}

cplx g_of_ten(cplx(*x)(const cplx &)) // this works
{
    return (*x)(10);
}


int main()
{
    //cout << f_of_ten(std::sqrt<double>) << endl; // compile ERROR here!!!
    std::cout << g_of_ten(std::sqrt) << std::endl;
}

Upvotes: 0

Views: 668

Answers (2)

Baum mit Augen
Baum mit Augen

Reputation: 50063

Bad idea, see comments and edit!

The std::sqrt for complex numbers is a template, if you use std::sqrt<double> your code works.

Not to sure why the g... variant works thou.

Edit to salvage this answer:

You can use a lambda to select the correct sqrt like

std::cout << f_of_ten([](cplx x){return std::sqrt(x);}) << std::endl;

Now template argument deduction and overload resolution will take place, select the right sqrt and pack it in the lambda which binds to std::function.

Upvotes: 1

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275405

There is more than one overload of std::sqrt and your code does not know how to determine which one you want.

Try:

typedef cplx(*complex_function)(const cplx &);

std::cout << f_of_ten( complex_function( std::sqrt ) ) << std::endl;

Upvotes: 2

Related Questions