c++ 如何组合 std::bind 和可变元组?

c++ how to combine std::bind and variadic tuples?

相关post:How to combine std::bind(), variadic templates, and perfect forwarding?

有没有办法用可变元组绑定一个函数?这里的错误代码表明了意图:

// t is an instance of T
auto f = std::bind(&T::iterate,t,???);
// args is an instance of std::tuple<Args...> args;
std::apply(f,args);

(注意:我不确定 "variadic tuple" 是否是正确的术语。期待通过您的更正来编辑 post)

不要使用 bind,而是使用 lambda:

auto f = [&t](auto... args){ t.iterate(args...); };
std::apply(f, args);

如果你想要完美转发,那看起来像:

auto f = [&t](auto&&... args){ t.iterate(std::forward<decltype(args)>(args)...); };
std::apply(f, args);

自 C++20 起您可以使用 std::bind_front:

template<class T>
void print (T val) {
    std::cout << val << std::endl;
}

struct T {
    template<class ... Args>
    void iterate(Args... args) {
        int temp[] = { (print(args),0)... };
    }
};

// all happens here
template<class ... Args>
void foo(const tuple<Args...>& args) {
    T t;
    auto f = std::bind_front(&T::iterate<Args...>,&t);
    std::apply(f,args);
}

// the call 
int i = 1;
foo(std::make_tuple(i,i+1,"bind is cool"));

如果您想使用旧的 std::bind,您可以提供自己的占位符,以便从包中生成:

template<int N>
struct MyPlaceholder {};

namespace std {
    template<int N>
    struct is_placeholder<MyPlaceholder<N>> : public integral_constant<int, N> {};
}

template<class ... Args, size_t ... Indices>
void foo2helper(const tuple<Args...>& args, std::index_sequence<Indices...>) {
    T t;
    auto f = std::bind(&T::iterate<Args...>,&t, (MyPlaceholder<Indices+1>{})...);
    std::apply(f,args);
}

template<class ... Args>
void foo2(const tuple<Args...>& args) {
    foo2helper(args, std::make_index_sequence<sizeof...(Args)>{});
}
// the call
foo2(std::make_tuple(2.34,"only bind"));

Live demo