pizzafilms pizzafilms - 3 months ago 17
C++ Question

Function pointer, Functor or Lambda?

I'm relatively new to C++, having spent years with Obj-C, and wondering about how to add what would be closure block in Obj-C, to a C++ class. Here's some pseudo code of what I want to do:

class Slider
{
public:
void onMouseDown()
{
if(rightClick or ctlKeyDown)
{
if(myFunctionPointer != nil)
{
// show popup menu
myFunctionPointer(this);
}
}
}

FunctionPointer myFunctionPointer = nil;
};


class Editor
{
public:
void showPopupMenu(Slider *s)
{
// build the popupMenu with information based on the slider
}

void init()
{
// create a slider and connect the popupMenu function to it
mySlider = new Slider;
mySlider->functionPointer = showPopupMenu();
}

Slider *mySlider;
};


As you can see, I'm trying to get my Slider class to call a function without knowing anything about it.

This shouldn't be that difficult, but I'm interested in doing it the best/proper way. Lambdas and functors look incredibly confusing. Maybe I'm looking for something else. But what?

Answer

Lambdas and functors are one of the most advanced C++ topics. You're better off starting with some fundamentals before, and have a solid understanding of how C++ classes work.

But, since you asked, the C++ equivalent of this should be something like this:

class Slider
{
public:
    void onMouseDown()
    {
        if(rightClick or ctlKeyDown)
        {
            if(myFunctionPointer)
            {
                // show popup menu
                myFunctionPointer(this);
            }
        }
    }

    std::function<void (Slider *)> myFunctionPointer=nullptr;
};


class Editor
{
public:
    void showPopupMenu(Slider *s)
    {
        // build the popupMenu with information based on the slider
    }

    void init()
    {
        // create a slider and connect the popupMenu function to it
        mySlider = new Slider;


        mySlider->functionPointer = [this](Slider *)
             {
                   showPopupMenu();
             };

    }

    Slider *mySlider;
};

As I said, I think that you're better off focusing your efforts on getting the fundamentals down pat, first, before plunging into these shark-infested waters.

And just to add some additional color: this will compile (the only thing that's missing is the definitions of rightClick or ctlKeyDown), but it may or may not be right, depending on the scope and the lifetime of the objects involved. It may or may not be necessary to have the lambda capture a std::shared_ptr, instead of this, depending on how the objects in this application get instantiated. Understanding how C++ objects work would be a necessary prerequisite before dealing with closures and callbacks, of this sort.

Comments