开发者

having "typedef void FuncCharPtr" in one class how to feed function that uses that typedef with non static functions?

开发者 https://www.devze.com 2023-02-07 03:52 出处:网络
So I have a class like: class IGraphElement{ // We should define prototype of functions that will be subscribers to our data

So I have a class like:

class IGraphElement{

    // We should define prototype of functions that will be subscribers to our data
    typedef void FuncCharPtr(char*, int) ;

public:
    // Function for adding subscribers functions
    void Add(FuncCharPtr* f)
    {
            //...
    }
 };

and another class like

#include "IGraphElement.h"

class  simpleRendererGraphElement : public IGraphElemen开发者_如何转开发t
{
  public:
    IGraphElement* charGenerator;
    // we owerrite init
    void Init(IGraphElement* CharGenerator)
    {
        charGenerator = CharGenerator;
        //we can to subscribe some function to our data generator
        charGenerator->Add(renderCastedData); // and here we receive C3867 
    }
    void renderCastedData(char* castedChar, int castedCharLength) //  our event system receives functions declared like void FuncCharPtr(char*, int) ;
    { }
};

why we get error C3867 and how to fix it not making functions static?


renderCastedData is a nonstatic member function. Its type is

void (simpleRendererGraphElement::*)(char*, int)

In order to call it, you need to have an instance of simpleRendererGraphElement for the this parameter. There are lots of solutions to this problem. One option would be to make Add a function template that takes anything that can be called with a char* and an int parameter:

template <typename Function>
void Add(Function f)

then you can write a function object to wrap the call:

struct RenderCastedDataFunctor
{
    simpleRendererGraphElement* obj_;

    RenderCastedDataFunctor(simpleRendererGraphElement* obj)
        : obj_(obj) { }

    void operator()(char* castedChar, int castedCharLength)
    {
        obj_->renderCastedData(castedChar, castedCharLength);
    }
};

and from your Init function you can call

charGenerator->Add(RenderCastedDataFunctor(this));

(The bind and function libraries from Boost, C++ TR1, and C++0x provide a generalized form of this pattern, allowing you to bind arguments to any callable entity and store those bound callable entities for later use. This particular approach here is just a dumbed down version that should work without any extra or possibly not supported libraries.)


typedef void FuncCharPtr(char*, int) ;

First of all, the above should be this,

typedef void (*FuncCharPtr)(char*, int) ;

Second, renderCastedData is not a function pointer; it's member-function pointer. So there is a difference. It's type is void (simpleRendererGraphElement::*)(char*, int);, not the above type!


A member function is not a regular function, and can't be assigned to a regular function pointer.

Use static member function, if renderCastedData needn't to be binded to any class instance.

If renderCastedData must be binded to a class instance, let IGraphElement::Add accept a member function pointer and a pointer to the class.

boost::function and boost::bind is also a good choice for the problem, they provide much more flexbility, but sometimes it can be a little slower.

0

精彩评论

暂无评论...
验证码 换一张
取 消