如何在C++17中定义函数组合以实现f(g(param))的计算?
实现C++函数组合f(g(param))的正确方式
看了你的代码,核心思路是对的,但有个明显的小问题:参数包params...在调用g的时候没展开——你写成了param(少了s),这会直接导致编译失败。另外还有几个可以优化的点,让函数更通用、更贴合C++现代编程风格。
修正后的实现代码
首先要确保包含utility头文件(std::forward依赖它),然后调整返回值类型和参数展开逻辑:
#include <utility> // 实现 f(g(params...)) 的完美转发函数组合 decltype(auto) fComposition(auto&& f, auto&& g, auto&&... params) { return std::forward<decltype(f)>(f)( std::forward<decltype(g)>(g)( std::forward<decltype(params)>(params)... ) ); };
关键细节解释
- 参数包展开:把
param改成params...,这样传入的所有参数都会被逐个转发给g,不管g需要1个还是多个参数(只要参数类型匹配即可)。 decltype(auto)返回值:它会精确推导f的返回类型,包括左值引用、右值引用或者值类型,避免不必要的拷贝或引用丢失。比如如果f返回const int&,函数组合的结果也会保持const int&类型。- 完美转发
std::forward:因为函数参数用了auto&&(万能引用),std::forward会保留每个参数的原始值类别(左值/右值),确保传递给f和g的参数语义正确——比如右值不会被意外转成左值,避免移动语义失效。
完整测试示例
补全你没写完的测试代码,举两个实用的组合例子:
#include <random> #include <cmath> #include <iostream> // 上面的fComposition函数放在这里 int main() { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<double> dist(0.0, 100.0); // 示例1:g生成随机数,f计算平方根 → sqrt(随机数) auto generate_random = [&]() { return dist(gen); }; auto calculate_sqrt = [](double x) { return std::sqrt(x); }; double random_sqrt = fComposition(calculate_sqrt, generate_random); // 示例2:g计算平方,f计算平方根 → sqrt(x²) = |x| auto square = [](double x) { return x * x; }; double abs_result = fComposition(calculate_sqrt, square, -7.5); std::cout << "Square root of random number: " << random_sqrt << '\n'; std::cout << "Absolute value via composition: " << abs_result << '\n'; return 0; }
编译运行
用你原本的命令编译即可:
g++ -std=c++17 src.cpp -o function_composition ./function_composition
内容的提问来源于stack exchange,提问作者user7122867
相关产品推荐
相关产品推荐

