我想在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))
有人可以帮忙把它编译好吗?
答案 0 :(得分:2)
正如@ 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::bind
或std::function
实施,请将boost::
和std::
替换为std::tr1::
对应项。另请注意,如果您有C ++ 11编译器,则可以使用lambda而不是bind
。
答案 1 :(得分:1)
应该是:
b_inst.foreach_x_do(f);
您还需要使f
静态,而不是非静态成员方法,因为foreach_x_do
函数的原始签名是针对独立函数指针,而不是指向成员的指针-功能。那就是,
static void f(int x) { }
答案 2 :(得分:1)
函数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));
}
答案 3 :(得分:0)
在这一行:
b_inst.foreach_x_do(f)();
删除第二组括号;你不需要它们。
b_inst.foreach_x_do(f);
应该可以正常工作。
答案 4 :(得分:0)
f()
是一个成员函数 - 所以它的相关性仅限于它的相应对象。到目前为止,其中一些解决方案无效。
你有两个选择,要么将函数设为静态,在这种情况下,哪个对象无关紧要,或以某种方式传递对象。
第二种方法在this helpful FAQ中明确解释了传递成员函数。
答案 5 :(得分:-2)
尝试:
class b{
int *x;
public:
void foreach_x_do(void (*f)(int)){
while(*x++) // or any kind of iteration through x
(*f)(*x);
}
};