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"));
相关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"));