将成员函数作为参数 / C++ 传递
passing member functions as parameters / c++
我想在 c++ 中实现一个类 b,在其中可以通过封装该迭代器类型的成员集进行某种迭代。喜欢:
b_object.for_each_x_do(function_f);
所以function_f会让每个X成员都做任何事情。比方说:
void function_f(x_member_type x){ cout << x << endl; }
还行。所以我试图通过这样的代码来实现这一点:
class b{
int *x;
public:
void foreach_x_do(void (*f)(int)){
while(*x++) // or any kind of iteration through x
f(*x);
}
};
class a{
b b_inst;
public:
void f(int x) { }
a(){
b_inst.foreach_x_do(f); // by mistake it was b_inst.foreach_x_do(f)(), however this wasn't the point at all.
}
~a(){}
};
int main(){}
但是,我在编译时收到此错误:
fp.cpp:在构造函数
‘a::a()’
中:
FP.cpp:17:错误:调用‘b::foreach_x_do(<unresolved overloaded function type>)’
没有匹配函数 FP.cpp:6:注:候选人是:void b::foreach_x_do(void (*)(int))
有人可以帮助编译它吗?
正如@steveo225所指出的,在这种情况下,f
的类型是void (a::*)(int)
而不是void (*)(int)
。有两种方法可以解决此问题 - 第一种方法是使b::foreach_x_do
成为采用任何可调用类型的成员函数模板:
class b {
int* x;
public:
b() : x() { }
template<typename F>
void foreach_x_do(F f) {
while(*x++)
f(*x);
}
};
class a {
b b_inst;
public:
void f(int x) { }
a() : b_inst() {
b_inst.foreach_x_do(std::bind(&a::f, this, _1));
}
};
第二种是保留b::foreach_x_do
非模板,并让它采用std::function<>
而不是函数指针:
class b {
int* x;
public:
b() : x() { }
void foreach_x_do(std::function<void(int)> const& f) {
while(*x++)
f(*x);
}
};
class a {
b b_inst;
public:
void f(int x) { }
a() : b_inst() {
b_inst.foreach_x_do(std::bind(&a::f, this, _1));
}
};
无论哪种情况,如果编译器太旧而无法随std::
或std::tr1::
实现一起提供,请将 std::bind
和 std::function
替换为其boost::
对应项。另请注意,如果您有 C++11 编译器,则可以使用 lambda 而不是 bind
。
它应该只是:
b_inst.foreach_x_do(f);
您还需要f
静态而不是非静态成员方法,因为 foreach_x_do
函数的原始签名是用于独立函数指针,而不是指向成员函数的指针。 所以即,
static void f(int x) { }
for_each_x_do
需要一个函数指针,而你(尝试)给它一个成员函数指针。两者是不一样的。前者可以直接调用,而后者需要调用对象实例。我建议你改用std::function
或boost::function
。像这样:
void for_each_x_do(function<void (int)> f) {
// your code here
}
然后使用绑定器构造函数对象:
a(){
b_inst.foreach_x_do(bind(&a::f, this, _1));
}
在这一行中:
b_inst.foreach_x_do(f)();
删除第二组括号;您不需要它们。
b_inst.foreach_x_do(f);
应该工作正常。
f()
是一个成员函数 - 因此它的相关性仅限于其相应的对象。 到目前为止,其中一些解决方案将不起作用。
您有两种选择,要么使函数静态,在这种情况下,哪个对象无关紧要,要么以某种方式传递对象。
第二种方法在此有用的常见问题解答中进行了明确说明,特别是有关传递成员函数的信息。
尝试:
class b{
int *x;
public:
void foreach_x_do(void (*f)(int)){
while(*x++) // or any kind of iteration through x
(*f)(*x);
}
};
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 将对象数组的引用传递给函数
- Pybind11:将元组列表从Python传递到C++
- std::向量与传递值的动态数组
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 使用指向成员的指针将成员函数作为参数传递
- Ctypes wstring通过引用传递
- C++数组传递给大小为的函数
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- C++/传递值导致#DEN
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何将参数传递给正在使用模板的类
- 将重载的成员函数传递给函数模板
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 通过JNI传递数据数组的最快方法是什么
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 通过网络、跨平台传递std::变体是否安全
- 在C++中传递给函数时,为什么要指定数组大小作为参数