Rella
Rella

Reputation: 66965

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

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 IGraphElement
{
  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?

Upvotes: 0

Views: 263

Answers (3)

hpsMouse
hpsMouse

Reputation: 2014

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.

Upvotes: 1

James McNellis
James McNellis

Reputation: 355187

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.)

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361612

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!

Upvotes: 1

Related Questions