1

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

Is there a way to bind a function with variadic tuples ? Here incorrect code indicating the intent:

// 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);

(note: I am unsure "variadic tuple" to be the right terminology. Looking forward editing the post with your correction)

Vince
  • 3,979
  • 10
  • 41
  • 69

2 Answers2

3

Since C++20 you can use 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"));

If you want to use old std::bind, you can provide your own placeholders to be generated from pack:

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

rafix07
  • 20,001
  • 3
  • 20
  • 33
2

Don't use bind, use a lambda instead:

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

If you want perfect forwarding, that would look like:

auto f = [&t](auto&&... args){ t.iterate(std::forward<decltype(args)>(args)...); };
std::apply(f, args);
NathanOliver
  • 171,901
  • 28
  • 288
  • 402