c_cpp C ++ 14中的函数currying(function_traits.cpp:https://gist.github.com/Garciat/cafe27d04cfdff0e891e) Posted 2021-05-14
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp C ++ 14中的函数currying(function_traits.cpp:https://gist.github.com/Garciat/cafe27d04cfdff0e891e)相关的知识,希望对你有一定的参考价值。
#include "curry.cpp"
#include "meow.cpp"
#include <iostream>
int main() {
{
auto add = curry([](meow, int a, int b, int c) { return a + b + c; });
std::cout << add(meow{})(5)(5)(5) << std::endl;
}
meow::report();
}
#include <type_traits>
#include <utility>
#include <tuple>
#include "function_traits.cpp"
// ---
template <typename Args, typename Params>
struct apply_args;
template <typename HeadArgs, typename... Args, typename HeadParams, typename... Params>
struct apply_args<std::tuple<HeadArgs, Args...>, std::tuple<HeadParams, Params...>>
: std::enable_if<
std::is_constructible<HeadParams, HeadArgs>::value,
apply_args<std::tuple<Args...>, std::tuple<Params...>>
>::type
{ };
template <typename... Params>
struct apply_args<std::tuple<>, std::tuple<Params...>> {
using type = std::tuple<Params...>;
};
// ---
using empty_tuple_t = std::tuple<>;
template <typename TupleType>
struct is_empty_tuple : std::false_type { };
template <>
struct is_empty_tuple<empty_tuple_t> : std::true_type { };
// ----
template <typename FType, typename Env, typename Params>
struct currying;
template <typename FType, typename... Env, typename... Params>
struct currying<FType, std::tuple<Env...>, std::tuple<Params...>> {
using function_type = FType;
using closure_env_type = std::tuple<Env...>;
using param_tuple_type = std::tuple<Params...>;
template <typename Func, typename... Args>
constexpr
currying(Func&& func, Args&&... args) :
func(std::move(func)),
env(std::forward<Args>(args)...)
{ }
template <typename... Args>
constexpr
auto operator() (Args&&... args) const& {
using ArgsTuple = std::tuple<Args...>;
using NewEnv = std::tuple<Env..., Args...>;
using NewParams = typename apply_args<ArgsTuple, param_tuple_type>::type;
using NewCurrying = currying<FType, NewEnv, NewParams>;
using EnvIndices = std::make_index_sequence<sizeof...(Env)>;
using CanExecute = is_empty_tuple<NewParams>;
return apply<NewCurrying, CanExecute>(EnvIndices{}, std::forward<Args>(args)...);
}
template <typename... Args>
constexpr
auto operator() (Args&&... args) && {
using ArgsTuple = std::tuple<Args...>;
using NewEnv = std::tuple<Env..., Args...>;
using NewParams = typename apply_args<ArgsTuple, param_tuple_type>::type;
using NewCurrying = currying<FType, NewEnv, NewParams>;
using EnvIndices = std::make_index_sequence<sizeof...(Env)>;
using CanExecute = is_empty_tuple<NewParams>;
return std::move(*this).template apply<NewCurrying, CanExecute>(EnvIndices{}, std::forward<Args>(args)...);
}
private:
template <typename NewCurrying, typename CanExecute, typename... Args, size_t... Indices>
constexpr
auto apply(std::index_sequence<Indices...>, Args&&... args) const& {
return apply<NewCurrying>(CanExecute{}, std::get<Indices>(env)..., std::forward<Args>(args)...);
}
template <typename NewCurrying, typename CanExecute, typename... Args, size_t... Indices>
constexpr
auto apply(std::index_sequence<Indices...>, Args&&... args) && {
return std::move(*this).template apply<NewCurrying>(CanExecute{}, std::get<Indices>(std::move(env))..., std::forward<Args>(args)...);
}
template <typename NewCurrying, typename... Args>
constexpr
auto apply(std::false_type, Args&&... args) const& {
return NewCurrying{ func, std::forward<Args>(args)... };
}
template <typename NewCurrying, typename... Args>
constexpr
auto apply(std::false_type, Args&&... args) && {
return NewCurrying{ std::move(func), std::forward<Args>(args)... };
}
template <typename NewCurrying, typename... Args>
constexpr
auto apply(std::true_type, Args&&... args) const {
return func(std::forward<Args>(args)...);
}
function_type func;
closure_env_type env;
};
// ---
template <typename FType>
constexpr
auto curry(FType&& func) {
using ArgsTuple = function_arg_tuple_t<FType>;
using CurryType = currying<FType, empty_tuple_t, ArgsTuple>;
return CurryType{ std::move(func) };
}
以上是关于c_cpp C ++ 14中的函数currying(function_traits.cpp:https://gist.github.com/Garciat/cafe27d04cfdff0e891e)的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp 使用一堆C ++ 11/14特性和“老派”C ++开发人员的单一函数甚至不再像C ++那样阅读.Specificall
Curry 通用量化函数
手写curry函数,实现函数柯里化
js函数柯里化的理解
js函数柯里化的理解
JS中的柯里化(currying)