将成员函数作为参数传递 / 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(<未解析的重载函数类型>)'
fp.cpp:6:注意:候选者是:void b::foreach_x_do(void (*)(int))
有人可以帮助编译它吗?
I would like to implement, in c++, a class b where it would be possible to do some kind of iteration through a member set encapsulating the type of that iterator. Like:
b_object.for_each_x_do(function_f);
so function_f would get everyone of the x members and do anything. Let's say:
void function_f(x_member_type x){ cout << x << endl; }
Ok. So I'm trying to achieve that through a code like:
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(){}
However, I'm getting this error, compile-time:
fp.cpp: In constructor
‘a::a()’
:
fp.cpp:17: error: no matching function for call to‘b::foreach_x_do(<unresolved overloaded function type>)’
fp.cpp:6: note: candidates are:void b::foreach_x_do(void (*)(int))
Anybody can help getting it to compile?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
正如 @steveo225 所指出的,在该上下文中
f
的类型为void (a::*)(int)
而不是void (*)(int)
代码>.有两种方法可以解决此问题 - 第一种是使b::foreach_x_do
成为采用任何可调用类型的成员函数模板:第二种是保留
b::foreach_x_do
> 非模板并让它采用std::function<>
而不是函数指针:无论哪种情况,都替换
std::bind
和如果您的编译器太旧而无法与
实现。另请注意,如果您有 C++11 编译器,则可以使用 lambda 而不是std::
或std::tr1:: 一起发布,则 std::function
及其对应的boost::
版本bind
。As @steveo225 noted,
f
in that context is of typevoid (a::*)(int)
rather thanvoid (*)(int)
. There are two approaches to fixing this -- the first is to makeb::foreach_x_do
a member function template that takes any callable type:The second is to keep
b::foreach_x_do
a non-template and have it take astd::function<>
instead of a function pointer:In either case, replace
std::bind
andstd::function
with theirboost::
counterparts if your compiler is too old to ship withstd::
orstd::tr1::
implementations. Also note that if you have a C++11 compiler, you can use a lambda instead ofbind
.它应该是:
您还需要将
f
设为静态,而不是非静态成员方法,因为foreach_x_do
函数的原始签名是独立函数指针,不是指向成员函数的指针。所以也就是说,It should just be:
You also need to make
f
static, not a non-static member method since the original signature for yourforeach_x_do
function is for a stand-alone function pointer, not a pointer-to-member-function. So i.e.,函数
for_each_x_do
需要一个函数指针,而您(尝试)给它一个成员函数指针。两者并不相同。前者可以直接调用,而后者则需要一个对象实例来调用。我建议您使用std::function
或boost::function
代替。像这样:然后使用绑定器构造一个函数对象:
The function
for_each_x_do
is expecting a function pointer, while you're (trying) to give it a member function pointer. The two are not the same. The former can be called directly, while the latter requires an object instance to be called. I'd suggest you usestd::function
orboost::function
instead. Something like:And then use a binder to construct a function object:
在这一行中:
删除第二组括号;你不需要它们。
应该可以正常工作。
In this line:
Remove the second set of parenthesis; you don't need them.
should work fine.
f()
是一个成员函数——因此它的相关性仅限于其相应的对象。到目前为止,其中一些解决方案还行不通。您有两种选择,要么使函数静态,在这种情况下哪个对象并不重要,要么以某种方式传递该对象。
这个有用的常见问题解答中明确解释了第二种方法关于传递成员函数。
f()
is a member function -- so it's relevance is limited to it's corresponding object. Some of these solutions so far won't work.You have two choices, either make the function static, in which case it doesn't matter which object, or somehow also pass the object.
The second method is clearly explained in this helpful FAQ specifically about passing member functions.
尝试:
};
Try:
};