boost::bind()-类似的东西,但用于函数调用
boost::bind()-like thing, but for function calls
给定 boost::bind
或 std::
等价物,我可以这样做:
int f(int a, int b)
{
return a + b;
}
auto f_two = boost::bind(f, 1, 1);
因此 f_two()
将 return 2 通过有效地调用一个中间函数,该函数通过任何实现机制调用 f(1, 1)
,可能类似于:
double f_two_caller()
{
return f(stored_arg_1, stored_arg_2);
}
但是,我的用例是我想绑定一个前缀函数,所以我可以说:
auto f_print = boost::bind(printf, "Hello, world!\n");
auto f_print_and_two = boost::bind_with_prefix(f, f_print, 1, 1);
所以f_print_and_two()
有效执行:
double f_print_and_two_caller()
{
f_print(f_print.stored_arg_1);
return f(stored_arg_1, stored_arg_2);
}
我确定该技术有一个合适的名称,我可以用它来查找解决方案,但我现在想不出...
根据你的描述,我想这就是你要找的东西:
#include <cstdio>
#include <tuple>
#include <utility>
#include <functional>
template<class F, class PrefixF, class...Args>
auto wrap_call_prefix(F&& f, PrefixF&& pf, Args&&...args)
{
return [f = std::forward<F>(f),
pf = std::forward<PrefixF>(pf),
args = std::make_tuple(std::forward<Args>(args)...)]
{
pf();
return std::apply(f, args);
};
}
int main()
{
auto add = [](auto x, auto y) { return x + y; };
auto f_print = std::bind(printf, "Hello, world!\n");
auto f_print_and_two_caller = wrap_call_prefix(add, f_print, 1, 2);
printf("%d\n", f_print_and_two_caller());
}
std::apply
是 c++17.
如果我是你,我就不会复制 bind
功能,而只会做这样的事情,这非常简单:
template<class Pre, class U>
class with_prefix_class{
public:
template<class V, class W>
with_prefix_class(V &&v, W &&w) : pre_(std::forward<V>(v)), func_(std::forward<W>(w)){}
decltype(std::declval<U>()()) operator()(){
pre_();
return func_();
}
private:
Pre pre_;
U func_;
};
int f(int a, int b)
{
return a + b;
}
template<class Pre, class U>
with_prefix_class<Pre, U> with_prefix(Pre &&pre, U &&u){
return with_prefix_class<Pre, U>(std::forward<Pre>(pre), std::forward<U>(u));
}
int main(int argc, char* argv[]) {
auto a = with_prefix([](){}, std::bind(f, 5, 3));
a();
}
template<class First, class Second>
struct compose_t {
First first;
Second second;
template<class...Args>
auto operator()(Args&&...args)
-> decltype( std::declval<Second&>()( std::declval<First&>()( std::declval<Args>()... ) ) )
{ return second(first( std::forward<Args>(args)... ) ); }
};
template<class First, class Second>
compose_t<typename std::decay<First>::type, typename std::decay<Second>::type>
compose( First&& first, Second&& second ){ return {std::forward<First>(first), std::forward<Second>(second)}; }
这是功能组合。
auto f_print = std::bind(printf, "Hello, world!\n");
auto f_print_and_two = std::bind( compose(f, f_print), 1, 1 );
int main() {
f_print_and_two();
}
和done.
请注意,函数组合可以链接。你甚至可以根据上面写一个可变的 compose
函数。
给定 boost::bind
或 std::
等价物,我可以这样做:
int f(int a, int b)
{
return a + b;
}
auto f_two = boost::bind(f, 1, 1);
因此 f_two()
将 return 2 通过有效地调用一个中间函数,该函数通过任何实现机制调用 f(1, 1)
,可能类似于:
double f_two_caller()
{
return f(stored_arg_1, stored_arg_2);
}
但是,我的用例是我想绑定一个前缀函数,所以我可以说:
auto f_print = boost::bind(printf, "Hello, world!\n");
auto f_print_and_two = boost::bind_with_prefix(f, f_print, 1, 1);
所以f_print_and_two()
有效执行:
double f_print_and_two_caller()
{
f_print(f_print.stored_arg_1);
return f(stored_arg_1, stored_arg_2);
}
我确定该技术有一个合适的名称,我可以用它来查找解决方案,但我现在想不出...
根据你的描述,我想这就是你要找的东西:
#include <cstdio>
#include <tuple>
#include <utility>
#include <functional>
template<class F, class PrefixF, class...Args>
auto wrap_call_prefix(F&& f, PrefixF&& pf, Args&&...args)
{
return [f = std::forward<F>(f),
pf = std::forward<PrefixF>(pf),
args = std::make_tuple(std::forward<Args>(args)...)]
{
pf();
return std::apply(f, args);
};
}
int main()
{
auto add = [](auto x, auto y) { return x + y; };
auto f_print = std::bind(printf, "Hello, world!\n");
auto f_print_and_two_caller = wrap_call_prefix(add, f_print, 1, 2);
printf("%d\n", f_print_and_two_caller());
}
std::apply
是 c++17.
如果我是你,我就不会复制 bind
功能,而只会做这样的事情,这非常简单:
template<class Pre, class U>
class with_prefix_class{
public:
template<class V, class W>
with_prefix_class(V &&v, W &&w) : pre_(std::forward<V>(v)), func_(std::forward<W>(w)){}
decltype(std::declval<U>()()) operator()(){
pre_();
return func_();
}
private:
Pre pre_;
U func_;
};
int f(int a, int b)
{
return a + b;
}
template<class Pre, class U>
with_prefix_class<Pre, U> with_prefix(Pre &&pre, U &&u){
return with_prefix_class<Pre, U>(std::forward<Pre>(pre), std::forward<U>(u));
}
int main(int argc, char* argv[]) {
auto a = with_prefix([](){}, std::bind(f, 5, 3));
a();
}
template<class First, class Second>
struct compose_t {
First first;
Second second;
template<class...Args>
auto operator()(Args&&...args)
-> decltype( std::declval<Second&>()( std::declval<First&>()( std::declval<Args>()... ) ) )
{ return second(first( std::forward<Args>(args)... ) ); }
};
template<class First, class Second>
compose_t<typename std::decay<First>::type, typename std::decay<Second>::type>
compose( First&& first, Second&& second ){ return {std::forward<First>(first), std::forward<Second>(second)}; }
这是功能组合。
auto f_print = std::bind(printf, "Hello, world!\n");
auto f_print_and_two = std::bind( compose(f, f_print), 1, 1 );
int main() {
f_print_and_two();
}
和done.
请注意,函数组合可以链接。你甚至可以根据上面写一个可变的 compose
函数。