将成员函数作为参数传递 / c++

发布于 2024-11-08 11:57:13 字数 1027 浏览 0 评论 0原文

我想在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

盗心人 2024-11-15 11:57:13

正如 @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::std::tr1:: 一起发布,则 std::function 及其对应的 boost:: 版本 实现。另请注意,如果您有 C++11 编译器,则可以使用 lambda 而不是 bind

As @steveo225 noted, f in that context is of type void (a::*)(int) rather than void (*)(int). There are two approaches to fixing this -- the first is to make b::foreach_x_do a member function template that takes any callable type:

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));
    }
};

The second is to keep b::foreach_x_do a non-template and have it take a std::function<> instead of a function pointer:

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));
    }
};

In either case, replace std::bind and std::function with their boost:: counterparts if your compiler is too old to ship with std:: or std::tr1:: implementations. Also note that if you have a C++11 compiler, you can use a lambda instead of bind.

撑一把青伞 2024-11-15 11:57:13

它应该是:

b_inst.foreach_x_do(f);

您还需要将 f 设为静态,而不是非静态成员方法,因为 foreach_x_do 函数的原始签名是独立函数指针,不是指向成员函数的指针。所以也就是说,

static void f(int x) {  } 

It should just be:

b_inst.foreach_x_do(f);

You also need to make f static, not a non-static member method since the original signature for your foreach_x_do function is for a stand-alone function pointer, not a pointer-to-member-function. So i.e.,

static void f(int x) {  } 
月下客 2024-11-15 11:57:13

函数 for_each_x_do 需要一个函数指针,而您(尝试)给它一个成员函数指针。两者并不相同。前者可以直接调用,而后者则需要一个对象实例来调用。我建议您使用 std::functionboost::function 代替。像这样:

void for_each_x_do(function<void (int)> f) {
  // your code here
}

然后使用绑定器构造一个函数对象:

a(){
  b_inst.foreach_x_do(bind(&a::f, this, _1));     
}

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 use std::function or boost::function instead. Something like:

void for_each_x_do(function<void (int)> f) {
  // your code here
}

And then use a binder to construct a function object:

a(){
  b_inst.foreach_x_do(bind(&a::f, this, _1));     
}
时光磨忆 2024-11-15 11:57:13

在这一行中:

 b_inst.foreach_x_do(f)();

删除第二组括号;你不需要它们。

 b_inst.foreach_x_do(f);

应该可以正常工作。

In this line:

 b_inst.foreach_x_do(f)();

Remove the second set of parenthesis; you don't need them.

 b_inst.foreach_x_do(f);

should work fine.

旧竹 2024-11-15 11:57:13

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.

疯狂的代价 2024-11-15 11:57:13

尝试:

class b{
int *x;
public:
void foreach_x_do(void (*f)(int)){
        while(*x++)  // or any kind of iteration through x
                (*f)(*x);
}

};

Try:

class b{
int *x;
public:
void foreach_x_do(void (*f)(int)){
        while(*x++)  // or any kind of iteration through x
                (*f)(*x);
}

};

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文