如何在 std::function 中存储 std::sqrt

How to store std::sqrt in std::function

std::sqrt()std::complex<T>(const std::complex<T>&) 类型。为什么我不能将它存储在 std::function 中?我得到的错误是:

error: conversion from ‘’ to non-scalar type ‘std::function(const std::complex&)>’ requested

Run it here:

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

关于您代码中的行:

std::function<Complex(const Complex&)> f = std::sqrt;

您必须考虑到 std::sqrt() 不是 不是 普通函数而是 函数模板:

template<class T>
complex<T> sqrt(const complex<T>& z);

您根据 std::complex class 模板定义了 Complex

using Complex = std::complex<double>;

因为 std::complex 包含对应于传递的 模板参数 成员类型 value_type(即, double 在这种情况下),你可以这样做:

std::function<Complex(const Complex&)> f = std::sqrt<Complex::value_type>;

这相当于直接将double作为模板参数传递给std::sqrt()

std::function<Complex(const Complex&)> f = std::sqrt<double>;

但是,前者比后者更通用,因为它允许您更改 std::complex 的模板参数——例如,使用 intfloat 而不是 double – 无需编辑与作业对应的源代码。


从 C++14 开始,您还可以通过 通用 lambda 包装对 std::sqrt() 的调用,并将此 lambda 分配给 std::function 对象:

std::function<Complex(const Complex&)> f = [](auto const& x) { 
   return std::sqrt(x); 
};

您只是忘记了作业的模板参数。

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

int main(){
    using Complex = std::complex<double>;
    std::function<Complex(const Complex&)> f = std::sqrt<double>;
    std::cout << "sqrt(4): " << f(std::complex<double>(4,0)) << "\n";
    return 0;
}