我知道是否有办法使用std :: mem_fun传递参数? 我想确切地说,我可以拥有尽可能多的论点和许多成员函数 问题是我处于一个旧的标准,我正在寻找一个完整的标准方式,因此即使我知道我可以轻松地做到这一点,也不允许提升作为答案= /
以下是我想如何使用它的一个小例子:
#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;
}
答案 0 :(得分:11)
通过std::bind
和std::bind1st
std::bind2nd
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)
);
答案 1 :(得分:1)
请参阅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
发生。我经常发现,通过一些思考,我可以找到一个更合适的算法,它经常消除对此命令的任何需要。
答案 2 :(得分:1)
您可以通过绑定:
using std::placeholders::_1
int a;
std::for_each(list.begin(), list.end(), std::bind(&Interface::do_something, _1, a));
答案 3 :(得分:0)
自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!