与std::bind相反,给定参数传入不同的函数
Opposite of std::bind, pass in different functions for given parameters
我有几个签名几乎相同的函数(比实际代码短得多):
int hello(A a, B b, C c, int n);
int there(A a, B b, C c, int n);
int how(A a, B b, C c, int n);
int are(A a, B b, C c, int n);
...
等等。然后在调用期间,代码创建参数一次,然后将相同的对象传递给每个函数,除了 n:
A a; B b; C c;
hello(a, b, c, 240);
there(a, b, c, 33);
how(a, b, c, 54);
are(a, b, c, 67);
我想要实现的是类似于 std::bind
通常使用的方式,只是我想换出该功能。例如:
auto uber_func = std::something_stack_overflow_recommends(..., a, b, c)
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
从 std::bind
的文档中我不清楚它是否可以做到这一点。你有什么建议吗?
您可以使用 Lambda,它使 std::bind
大部分已过时,因为它更易于使用:
auto uber_func = [&](std::function<int(A, B, C, int)> f, int n) {
return f(a, b, c, n);
};
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
第一个解决方案强制所有函数都具有相同的众所周知的接口。如果需要,它可以被推广以支持不同类型的功能:
auto uber_func = [&](auto f, int n) {
return f(a, b, c, n);
};
第二种解决方案更通用,避免了第一种解决方案的性能开销。小缺点:它将需要一个 C++14 编译器,而第一个应该适用于任何 C++11 编译器。如果这没问题,我更喜欢第二种解决方案而不是第一种解决方案。
我知道你问的是如何用 std::bind
做,我没有回答。但是,自从 C++11 Lambda 很大程度上取代了 std::bind
。自 C++14 以来,它更加清晰,因为添加了进一步的改进。除非与 C++98 的兼容性是一个严格的要求,否则我建议 avoid std::bind
in favor of Lambdas.
您可以使用除最后一个以外的所有参数构造一个对象:
template<typename A, typename B, typename C>
struct uber
{
A a;
B b;
C c;
uber(A a, B b, C c) : a(a), b(b), c(c) {}
template<typename F>
auto operator()(F f, int n) { f(a,b,c,n); }
};
然后使用模板调用运算符调用各个函数:
A a; B b; C c;
auto uber_func = uber{a,b,c};
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
我有几个签名几乎相同的函数(比实际代码短得多):
int hello(A a, B b, C c, int n);
int there(A a, B b, C c, int n);
int how(A a, B b, C c, int n);
int are(A a, B b, C c, int n);
...
等等。然后在调用期间,代码创建参数一次,然后将相同的对象传递给每个函数,除了 n:
A a; B b; C c;
hello(a, b, c, 240);
there(a, b, c, 33);
how(a, b, c, 54);
are(a, b, c, 67);
我想要实现的是类似于 std::bind
通常使用的方式,只是我想换出该功能。例如:
auto uber_func = std::something_stack_overflow_recommends(..., a, b, c)
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
从 std::bind
的文档中我不清楚它是否可以做到这一点。你有什么建议吗?
您可以使用 Lambda,它使 std::bind
大部分已过时,因为它更易于使用:
auto uber_func = [&](std::function<int(A, B, C, int)> f, int n) {
return f(a, b, c, n);
};
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);
第一个解决方案强制所有函数都具有相同的众所周知的接口。如果需要,它可以被推广以支持不同类型的功能:
auto uber_func = [&](auto f, int n) {
return f(a, b, c, n);
};
第二种解决方案更通用,避免了第一种解决方案的性能开销。小缺点:它将需要一个 C++14 编译器,而第一个应该适用于任何 C++11 编译器。如果这没问题,我更喜欢第二种解决方案而不是第一种解决方案。
我知道你问的是如何用 std::bind
做,我没有回答。但是,自从 C++11 Lambda 很大程度上取代了 std::bind
。自 C++14 以来,它更加清晰,因为添加了进一步的改进。除非与 C++98 的兼容性是一个严格的要求,否则我建议 avoid std::bind
in favor of Lambdas.
您可以使用除最后一个以外的所有参数构造一个对象:
template<typename A, typename B, typename C>
struct uber
{
A a;
B b;
C c;
uber(A a, B b, C c) : a(a), b(b), c(c) {}
template<typename F>
auto operator()(F f, int n) { f(a,b,c,n); }
};
然后使用模板调用运算符调用各个函数:
A a; B b; C c;
auto uber_func = uber{a,b,c};
uber_func(hello, 240);
uber_func(there, 33);
uber_func(how, 54);
uber_func(are, 67);