如何使用std::mem_fun传递参数
How passing arguments using std::mem_fun
我想知道是否有一种方法可以使用std::mem_fun传递参数?我想准确地说,我可以有尽可能多的论据和大量的成员函数
问题是,我使用的是旧标准,我正在寻找一种完整的stl方式,所以即使我知道我可以很容易地做到,也不允许将助推作为答案=/
下面是我想如何使用它的一个小插图:
#include <list>
#include <algorithm>
// Class declaration
//
struct Interface {
virtual void run() = 0;
virtual void do_something(int) = 0;
virtual void do_func(int, int) = 0;
};
struct A : public Interface {
void run() { cout << "Class A : run" << endl; }
void do_something(int foo) { cout << "Class A : " << foo << endl; }
void do_func(int foo, int bar) { cout << "Class A : " << foo << " " << bar << endl; }
};
struct B : public Interface {
void run() { cout << "Class B : run" << endl; }
void do_something(int foo) { cout << "Class B : " << foo << endl; }
void do_func(int foo, int bar) { cout << "Class B : " << foo << " " << bar << endl; }
};
// Main
//
int main() {
// Create A and B
A a;
B b;
// Insert it inside a list
std::list<Interface *> list;
list.push_back(&a);
list.push_back(&b);
// This works
std::for_each(list.begin(), list.end(), std::mem_fun(&Interface::run));
// But how to give arguments for those member funcs ?
std::for_each(list.begin(), list.end(), std::mem_fun(&Interface::do_something));
std::for_each(list.begin(), list.end(), std::mem_fun(&Interface::do_func));
return 0;
}
通过std::bind1st
和std::bind2nd
使用std::bind
std::for_each(list.begin(), list.end(),
std::bind2nd(std::mem_fun(&Interface::do_something),1) // because 1st is this
);
不幸的是,该标准对双参数版本没有帮助,您需要编写自己的:
struct MyFunctor
{
void (Interface::*func)(int,int);
int a;
int b;
MyFunctor(void (Interface::*f)(int,int), int a, int b): func(f), a(a), b(b) {}
void operator()(Interface* i){ (i->*func)(a,b);}
};
std::for_each(list.begin(), list.end(),
MyFunctor(&Interface::do_func, 1, 2)
);
Lambda版本
最初的答案早在2012年就很好了,当时Lambda的编译器刚刚被添加到标准中,很少有编译器符合C++11。8年后的今天,大多数编译器都兼容C++11,我们可以使用它来简化这些事情。
// Binding 1 parameter
std::for_each(list.begin(), list.end(),
[](auto act){act->do_something(1);})
// Binding 2 parameters
std::for_each(list.begin(), list.end(),
[](auto act){act->do_func(1, 2);})
您可以通过绑定:
using std::placeholders::_1
int a;
std::for_each(list.begin(), list.end(), std::bind(&Interface::do_something, _1, a));
参见std::bind1st
和std::bind2nd
。它们使用起来相当笨拙和丑陋,但如果你坚持只使用C++03中现有的内容,而不添加任何内容,那么它们几乎就是所有可用的内容。
编辑:当/如果我需要这样做时,我通常使用一个小的函子类来完成,而不是使用std::bind1st
和/或std::bind2nd
。这最终与它们产生的内容没有太大区别,但(IMO)它通常更具可读性。
template<class T>
class invoke_do_something {
int value;
public:
adder(int x) : value(x) {}
void operator()(T &t) {
t.do_something(value);
}
};
std::for_each(list.begin(), list.end(), invoke_do_something(1));
然而,我自己的看法是,大多数时候这只是一种创可贴。它经常使用for_each
。我通常会发现,经过一些思考,我可以找到一个更合适的算法,它经常完全不需要这个顺序上的任何东西。
由于c++20
,您不需要std::bind
和族。您可以使用std::mem_fn
执行此操作。请注意,std::mem_fun
在c++20
中不可用
#include <functional>
#include <iostream>
#include <string>
struct Foo {
void display_number(int i, char ch, std::string s) {
std::cout << "number: " << i << " character: " << ch << " string: " << s << 'n';
}
};
int main() {
Foo f;
auto print_num = std::mem_fn(&Foo::display_number);
print_num(f, 42, 'a', "Hello!");
}
输出:
number: 42 character: a string: Hello!
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何使用以下参数调用函数:fun(Ty-param[NUM])