gpt4 book ai didi

c++ - 滥用逗号运算符来柯里化(Currying)函数参数

转载 作者:行者123 更新时间:2023-11-30 02:13:40 24 4
gpt4 key购买 nike

在某些语言中,调用函数时可以省略括号。

frobnicate foo, bar, baz, qux

让我们看看是否可以将它或类似的东西引入 C++。这几乎肯定意味着滥用逗号运算符,但据我所知,没有办法扩展任意类型以具有重载的逗号运算符。所以像代理 currier 类型的东西可以工作。

comma_curry(frobnicate), foo, bar, baz, qux;

comma_curry(我不擅长起名字)可能是某种递增的 currier,其逗号运算符一次接受一个参数。理想情况下,我希望它具有完美的转发语义,这样它与直接调用 frobnicate 没有什么不同。

frobnicate(foo, bar, baz, qux);

特别是如果一些参数本身是函数调用,可能会返回纯右值。

frobnicate(foo(), bar, baz(), qux);

我试过并想出了 a non-working example ,使用从另一篇文章复制的一些帮助代码。任何人有一些好的或更好的想法? 👀

最佳答案

当然,所有这些对于普通函数参数来说都是微不足道的。

除非用于学习和玩具示例,否则我不建议使用逗号运算符。不要将其放入生产代码中。

但是使用逗号运算符对于增量和重新柯里化(Currying)也很有趣。这是一个工作示例:

template<typename F, typename... Curry>
struct comma_curry {
template<typename... C>
explicit comma_curry(F function, C&&... c) noexcept :
function(std::move(function)), curry{std::forward<C>(c)...} {}

template<typename T>
friend auto operator,(comma_curry&& self, T&& arg) -> comma_curry<F, Curry..., std::decay_t<T>> {
return std::apply([&](auto&&... curry) {
return comma_curry<F, Curry..., std::decay_t<T>>(std::move(self.function), std::forward<decltype(curry)>(curry)..., std::forward<T>(arg));
}, std::move(self.curry));
}

template<typename... Args>
auto operator()(Args&&... args) const& -> decltype(auto) {
return std::apply([&](auto&&... curry) -> decltype(auto) {
return function(std::forward<decltype(curry)>(curry)..., std::forward<Args>(args)...);
}, curry);
}

template<typename... Args>
auto operator()(Args&&... args) && -> decltype(auto) {
return std::apply([&](auto&&... curry) -> decltype(auto) {
return std::move(function)(std::forward<decltype(curry)>(curry)..., std::forward<Args>(args)...);
}, std::move(curry));
}

private:
// [[no_unique_address]]
F function;

// [[no_unique_address]]
std::tuple<Curry...> curry;
};

它支持通过 std::ref 对引用进行柯里化(Currying),并且仅支持对移动类型进行柯里化(Currying)。

可以这样使用:

int main() {
auto function = [](int& i, double, std::unique_ptr<int>, std::tuple<int>) {
std::cout << "Called! i value: " << i << std::endl;
};

int number = 1;

// Reference arguments are sent using std::ref
auto curried = (comma_curry(function), std::ref(number), 1.5);
curried(std::make_unique<int>(), std::tuple{1});

number = 42;
auto recurried = (std::move(curried), std::make_unique<int>(), std::tuple{1});

// We curried a std::unique_ptr, our function is a one time call
// Since it's a one time call and destroy itself in the calling,
// it must be moved
std::move(recurried)();
}

Live example

关于c++ - 滥用逗号运算符来柯里化(Currying)函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58958367/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com