【问题标题】:How to store std::sqrt in std::function如何将 std::sqrt 存储在 std::function 中
【发布时间】:2020-03-05 14:02:04
【问题描述】:

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

错误:要求从“”转换为非标量类型“std::function(const std::complex&)>”

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

【问题讨论】:

    标签: c++ function c++11 templates function-pointers


    【解决方案1】:

    关于代码中的行:

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

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

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

    您根据std::complex 类模板定义了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); 
    };
    

    【讨论】:

    • 如果我该死的克莱恩没有问题,我会是第一个。 ;->
    • @Superlokkus 下次使用 vim。
    • 嗯... lambda 技巧是 C++11,它是后来出现的“自动”参数
    • @Swift-FridayPie 是的,但是autolambda 变成了 generic lambda,不是吗?据我了解,那是C++14 feature
    【解决方案2】:

    您只是忘记了分配的模板参数。

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

    【讨论】:

      猜你喜欢
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多