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;
}
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
.