模仿 c++17 中的 std::bind_front 来调用成员函数

dar*_*une 1 c++ higher-order-functions template-meta-programming c++17 bind-front

是否可以std::bind_front在 C++17 中轻松模仿?(仅对于成员函数包装就可以)

我查看了中的实现,旨在复制,但看起来它确实非常具体的实现

我在想 lambda 包装器或模板函数/对象可能有用吗?

(这里性能不是问题)

Mar*_*k R 5

这可以作为一个起点

template<typename F, typename ...FrontArgs>
struct bindfronthelper
{
    bindfronthelper(F f, FrontArgs&&...args)
        : mF{std::move(f)}
        , mFrontArg{std::forward<FrontArgs>(args)...}
    {}

    template<typename ...BackArgs>
    auto operator()(BackArgs&&...args) const
    {
        return std::apply(mF, std::tuple_cat(mFrontArg, std::forward_as_tuple(args...)));
    }

    F mF;
    std::tuple<std::decay_t<FrontArgs>...> mFrontArg;
};

template<typename F, typename ...FrontArgs>
auto mybindfront(F f, FrontArgs&&...args)
{
    return bindfronthelper<F, FrontArgs...>{std::move(f), std::forward<FrontArgs>(args)...};
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/Tz9fen

写得很快,没有经过很好的测试,所以在极端情况下可能会存在一些陷阱。至少它展示了如何实现这一目标。


好吧,我把这个搞得太复杂了,这是更简单的版本:

template<typename T, typename ...Args>
auto tuple_append(T&& t, Args&&...args)
{
    return std::tuple_cat(
        std::forward<T>(t),
        std::forward_as_tuple(args...)
    );
}

template<typename F, typename ...FrontArgs>
decltype(auto) mybindfront(F&& f, FrontArgs&&...frontArgs)
{
    return [f=std::forward<F>(f), 
            frontArgs = std::make_tuple(std::forward<FrontArgs>(frontArgs)...)]
            (auto&&...backArgs) 
        {
            return std::apply(
                f, 
                tuple_append(
                    frontArgs, 
                    std::forward<decltype(backArgs)>(backArgs)...)); 
        };
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/cqPjTY

仍然通过了我提供的所有测试。我保留旧版本,因为通过一些工作可以对其进行调整以适应旧的 C++ 标准。