首页 > 解决方案 > 来自标准的功能组成

问题描述

我正在尝试创建一个函数“compose”,返回作为参数给出的可调用对象的组合。

在数学中,它将是以下内容:

F = h(g(f(x)))

这里是 C++ 中的一个实现:

template <typename F>
auto compose(F&& f)
{
    return[f = std::forward<F>(f)](auto&&... args){
        return f(std::forward<decltype(args)>(args)...);
    };
}

template <typename F, typename G, typename... Functions>
auto compose(F&& f, G&& g, Functions&&... functions)
{
    return compose(
        [f = std::forward<F>(f), g = std::forward<G>(g)](auto&&... args)
        {
            return f(g(std::forward<decltype(args)>(args)...));
        },
        std::forward<Functions>(functions)...);
}

如果我提供 lambda 函数作为参数,这就像一个魅力:

auto f = compose(
    [](auto value) { return std::sin(value); },
    [](auto value) { return std::asin(value); }
);

但是,如果我直接使用标准中的重载函数(没有将它们封装在 lambda 中),编译器无法推断出选择哪个重载来实例化模板:

auto g = compose(
    std::sin,
    std::asin
);

这里使用 Microsoft C++ 编译器的错误:

error C2672: 'compose': no matching overloaded function found
error C2783: 'auto compose(F &&,G &&,Functions &&...)': could not deduce template argument for 'F'
message : see declaration of 'compose'
error C2783: 'auto compose(F &&,G &&,Functions &&...)': could not deduce template argument for 'G'
message : see declaration of 'compose'
error C2780: 'auto compose(F &&)': expects 1 arguments - 2 provided
message : see declaration of 'compose'

有没有办法在创建组合函数时声明我们想要使用的函数类型(std::sin 和 std::asin)?

标签: c++functional-programming

解决方案


过关怎么样(double (&)(double)) std ::sin


推荐阅读