C++中Lambda Curry表达式的优点是什么?

O C*_*nor -2 c++ lambda

我已经学会了如何在 C++ 中编写以下 lambda 表达式:

auto addCurry = [](auto &a) {
    return [&a](auto &b) {
        return [&a, &b] (auto &c){
            return a+b+c;
        };
    };
};

std::cout << addCurry("how")("are")("you?") << std::cout;
Run Code Online (Sandbox Code Playgroud)

我应用上述技术来连接字符串或对一些数字求和。我想知道为什么我应该在普通函数或普通内联字符串连接上引用上面的 lambda 表达式,如下所示?

auto my_function(auto &a, auto &b, auto &c) {
    return a + b + c;
}

std::string a = "aa", b="bb", c = "cc";
std::cout << my_function(a, b, c) << std::endl;

// or just...
std::string my_string = a + b + c;

// or just ...
int i = 1; j = 2; k = 3;
int my_i = i + j + k; 
Run Code Online (Sandbox Code Playgroud)

上面的 lambda 表达式有什么优点?什么时候在 C++ 中应用很有用?

Enr*_*lis 5

每当您必须调用固定某些参数的函数(通常是多次)时,柯里化和部分函数应用程序都很有用。

甚至还有一个库提供了柯里化或部分应用“函数”的工具:

#include <iostream>
#include <boost/hana/functional/curry.hpp>
#include <functional>
#include <iterator>
#include <ostream>
#include <vector>

using namespace boost::hana;

constexpr auto plus = boost::hana::curry<2>(std::plus<>{});

int main() {
    std::vector<int> v{1,2,3,4};
    std::ostream_iterator<int> os(std::cout, ",");
    std::transform(v.begin(), v.end(), os, plus(3)); // prints 4,5,6,7,
}
Run Code Online (Sandbox Code Playgroud)

显然,您可以手动进行柯里化,如您的示例所示,

constexpr auto plus = [](auto x){
    return [x](auto y){
        return x + y;
    };
};
Run Code Online (Sandbox Code Playgroud)

但你只是重新发明了一个名为 的小轮子std::plus<>{}。此外,你将无法像 那样调用它plus(x,y),而如果你通过 柯里化它,你就可以调用它hana::curry

你也可以定义

auto plus3(int x) {
    return x + 3;
}
Run Code Online (Sandbox Code Playgroud)

并使用

    std::transform(v.begin(), v.end(), os, plus3);
Run Code Online (Sandbox Code Playgroud)

但“代码可重用性”去哪儿了?


恕我直言,要感受到柯里化和部分函数应用的令人印象深刻的重要性,几乎必然需要拥抱至少一点函数式编程。

事实上,纯函数式编程语言 Haskell 将柯里化设为默认值,从某种意义上说,函数默认被柯里化:

twoPlusThree = 2 + 3 -- twoPlusThree is 5 (-- introduces a comment)
plus3 = (+ 3) -- we are applying the function + to just one argument
onePlusThree = plus3 1 -- onePlusThree is 4
Run Code Online (Sandbox Code Playgroud)