std::sqrt()
is of type std::complex<T>(const std::complex<T>&)
. Why can't I store it in this std::function
? The error I get is:
error: conversion from ‘’ to non-scalar type ‘std::function(const std::complex&)>’ requested
#include <complex>
#include <functional>
#include <iostream>
int main(){
using Complex = std::complex<double>;
std::function<Complex(const Complex&)> f = std::sqrt;
std::cout << "sqrt(4): " << f(std::complex<double>(4,0)) << "\n";
return 0;
}
Concerning the line in your code:
std::function<Complex(const Complex&)> f = std::sqrt;
You must take into account that std::sqrt()
is not an ordinary function but a function template:
template<class T>
complex<T> sqrt(const complex<T>& z);
You defined Complex
in terms of the std::complex
class template:
using Complex = std::complex<double>;
Since std::complex
contains the member type value_type
that corresponds to the passed template argument (i.e., double
in this case), you can just do:
std::function<Complex(const Complex&)> f = std::sqrt<Complex::value_type>;
This is equivalent to directly passing double
as template argument to std::sqrt()
:
std::function<Complex(const Complex&)> f = std::sqrt<double>;
However, the former is more generic than the latter because it allows you to change std::complex
's template argument – e.g., using int
or float
instead of double
– without having to edit the source code corresponding to the assignment.
Since C++14 you can also wrap the call to std::sqrt()
by means of a generic lambda and assign this lambda to the std::function
object:
std::function<Complex(const Complex&)> f = [](auto const& x) {
return std::sqrt(x);
};