C++成员函数指针和STL算法

发布于 2024-08-05 17:40:56 字数 837 浏览 5 评论 0原文

我有一个抽象仿函数类,它重载了operator() 和实现它的派生对象。

我有一个函数(另一个类的一部分),它尝试获取这些函子类的数组,并尝试将指向成员函数的指针传递给 std 算法 for_each(),这里是我正在做的事情的概述:

编辑:为了清楚起见,我已经重新清理了它并放置了旧的小示例。

class A{
  operator()(x param)=0;
  operator()(y param)=0;
}

class B: public A{
  operator()(x param); //implemented
  operator()(y param);
}
...// and other derived classes from A

void ClassXYZ::function(A** aArr, size_t aSize)
{
  ...//some code here

  for(size_t i = 0; i< aSize; i++){

    A* x = aArr[i];
    for(v.begin(), v.end(), ...//need to pass pointer/functor to right operator() of x here

..//other code
}

我尝试了几种方法,但不知道如何让它工作,我需要使用抽象类型,因为我可以有不同的派生类型,但它们都必须实现相同的运算符()(param x ) 功能。

我只需要 for_each() 函数就能够调用成员函数operator()(param x)。我有一个不同的函数,它有具体的实现,只需传递一个实例即可工作。我试图在这里达到类似的效果,但不知道我给出了哪些具体课程。

我做错了什么?

I have an abstract functor class that overloads operator() and derived objects that implement it.

I have a function (part of another class) that tries to take an Array of these functor classes and tries to pass a pointer to a member function to the std algorithm for_each(), here is a overview of what I'm doing:

EDIT: I have re-cleaned it and put the old small example for clarity.

class A{
  operator()(x param)=0;
  operator()(y param)=0;
}

class B: public A{
  operator()(x param); //implemented
  operator()(y param);
}
...// and other derived classes from A

void ClassXYZ::function(A** aArr, size_t aSize)
{
  ...//some code here

  for(size_t i = 0; i< aSize; i++){

    A* x = aArr[i];
    for(v.begin(), v.end(), ...//need to pass pointer/functor to right operator() of x here

..//other code
}

I've tried a few ways and I can't figure out how to get it to work, I need to use the abstract type as I could have different derived types but they will all have to implement the same operator()(param x) function.

I just need the for_each() function to be able to call the member function operator()(param x). I have a different function where it has concrete implementations and simply passes an instance of those and it works. I'm trying to achieve a similar effect here but without the knowledge of what concrete classes I'm given.

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

雨落□心尘 2024-08-12 17:40:56

你想要这样的东西......

std::for_each(
  it->second.begin(),
  it->second.end(),
  std::bind1st(std::mem_fun(&A::operator()),x)
);

You want something like this...

std::for_each(
  it->second.begin(),
  it->second.end(),
  std::bind1st(std::mem_fun(&A::operator()),x)
);
逆光下的微笑 2024-08-12 17:40:56

如果我明白你想要做什么,你的代码片段中有很多错误:

  • sizeof aArr 是错误的,你需要显式传递大小(ChrisW 注意到)
  • 缺少 virtual< operator()() 原始声明上的 /code> 说明符
  • 不确定您的 for 循环在哪里结束,因为没有匹配的 } (我怀疑它根本不应该在那里)

下面是一些代码,它将循环遍历 A (或 A 派生)对象的数组并调用 operator()< /code> 在每一个上,传递一个传入的参数作为 param 参数:

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef double param;      // Just for concreteness

class A {
public:
    virtual void operator()(param x) = 0;
};

class B : public A {
public:
    void operator()(param x) { cerr << "This is a B!  x==" << x << ".\n"; }
};

void function(A** aArr, size_t n, param theParam) {
    void (A::*sFunc)(param x) = &A::operator();
    for_each(aArr, aArr + n, bind2nd(mem_fun(sFunc), theParam));
}

int main(int argc, char** argv) {
    A* arr[] = { new B(), new B(), new B() };

    function(arr, 3, 42.69);

    delete arr[0];
    delete arr[1];
    delete arr[2];
    return 0;
}

mem_fun() 是将 1 参数成员函数指针转换为 2 参数所必需的-参数函数对象;然后,bind2nd() 生成一个 1 参数函数对象,该对象将提供给 function() 的参数固定为第二个参数。 (for_each() 需要一个 1 参数函数指针或函数对象。)

编辑: 基于 Alex Tingle 的回答,我推断您可能希望 function() 做很多事情单个 A 派生对象上的事物。在这种情况下,你会想要这样的东西:

void function(A** aArr, size_t n, vector<param> const& params) {
    for (size_t i = 0; i < n; ++i) {
        void (A::*sFunc)(param x) = &A::operator();
        for_each(params.begin(), params.end(), bind1st(mem_fun(sFunc), aArr[i]));
    }
}

If I understand what you want to do, there are quite a few errors in your code snippet:

  • sizeof aArr is wrong, you need to pass the size explicitly (noticed by ChrisW)
  • Missing virtual specifier on the original declaration of operator()()
  • Not sure where your for loop ends as there's no matching } (I suspect it shouldn't be there at all)

Here's some code that will loop through an array of A (or A-derived) objects and call operator() on each one, passing across a passed-in argument as the param parameter:

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef double param;      // Just for concreteness

class A {
public:
    virtual void operator()(param x) = 0;
};

class B : public A {
public:
    void operator()(param x) { cerr << "This is a B!  x==" << x << ".\n"; }
};

void function(A** aArr, size_t n, param theParam) {
    void (A::*sFunc)(param x) = &A::operator();
    for_each(aArr, aArr + n, bind2nd(mem_fun(sFunc), theParam));
}

int main(int argc, char** argv) {
    A* arr[] = { new B(), new B(), new B() };

    function(arr, 3, 42.69);

    delete arr[0];
    delete arr[1];
    delete arr[2];
    return 0;
}

mem_fun() is necessary to convert a 1-parameter member function pointer to a 2-parameter function object; bind2nd() then produces from that a 1-parameter function object that fixes the argument supplied to function() as the 2nd argument. (for_each() requires a 1-parameter function pointer or function object.)

EDIT: Based on Alex Tingle's answer, I infer that you might have wanted function() to do many things on a single A-derived object. In that case, you'll want something like:

void function(A** aArr, size_t n, vector<param> const& params) {
    for (size_t i = 0; i < n; ++i) {
        void (A::*sFunc)(param x) = &A::operator();
        for_each(params.begin(), params.end(), bind1st(mem_fun(sFunc), aArr[i]));
    }
}
远昼 2024-08-12 17:40:56

表达式“bar.*fn”不会计算为常规或非成员函数指针。
因此,您需要调用绑定函数( std::tr1::bind 或 boost::bind )来获取这样的函数。

The expression "bar.*fn" doesn't evaluate to regular, or non-member, function pointer.
So you need to call a binding function (either std::tr1::bind or boost::bind ) to obtain such a function.

溺ぐ爱和你が 2024-08-12 17:40:56

我无法使用当前格式使其工作,我认为它不喜欢我使用指向基本成员函数的指针并尝试调用这样的派生类实现的事实。

相反,我修改了代码以在基类中包含纯虚函数,这些函数在实现时将为每个派生类返回函子。我想不出还有什么其他可行的办法。但编译起来是这样的。

但我很好奇是否有人能够解决原始问题,而不必在基类中使用纯虚拟“创建函子”方法。

I couldn't get it work using the current format, I think it doesn't like the fact i'm using a Pointer to a base member function and trying to call a derived classes implementation like that.

Instead I modified the code to include pure virtual functions in the base class that will return functors for each derived class when implemented. I can't think of anything else that would work. But it compiles like this.

But I am curious if anyone has a solution to the original problem without having to use pure virtual "create functor" methods in the base class.

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