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