Trevor M
Trevor M

Reputation: 157

function pointers using functions in an object with parameters

I have been playing around with function pointers in c++ and seem to have found a bit of a problem. I made a demo to reproduce the error in a simple example.

I have the header file

class MyClass
{
public:
    void MyFunction(int i);
    MyClass();
    ~MyClass();
};

and the cpp file

#include "MyClass.h"
#include <iostream>
#include <functional>
using namespace std;

MyClass::MyClass()
{
    //doesn't work
    function<void(int)> func = &MyClass::MyFunction;
}

void MyClass::MyFunction(int i)
{
    cout << i << endl;
}

In the constructor of the cpp file I am trying to create a pointer to MyFunction. It gives the error error C2664: 'void std::_Func_class<_Ret,int>::_Set(std::_Func_base<_Ret,int> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,int> *' in the functional file at line 506. It works fine with a parameterless method, but not with them. Does anyone know why, and how to resolve it?

Upvotes: 2

Views: 607

Answers (2)

vsoftco
vsoftco

Reputation: 56567

You can also use std::mem_fn in C++11, which wraps a member function/variable into a callable closure

#include <iostream>
#include <functional>

class MyClass
{
public:
    MyClass()
    {
        auto func = std::mem_fn(&MyClass::MyFunction);
        func(this, 42); // call it on the current instance
    }
    void MyFunction(int i)
    {
        std::cout << i << std::endl;
    }
};

int main()
{
    MyClass foo;
}

or, you can explicitly specify the instance you're calling the pointer to member function

MyClass()
{
    auto func = &MyClass::MyFunction;
    (this->*func)(42); // call it on the current instance
}

In particular, note that std::function<void(int)> is not convertible to a pointer to member function. See related Using generic std::function objects with member functions in one class That's why using auto with std::mem_fn gets rid of all the pain.

Upvotes: 3

huu
huu

Reputation: 7482

You can use this and bind the object being constructed to the function. For instance, if your constructor looked like this:

MyClass::MyClass()
{
    function<void(int)> func = bind(&MyClass::MyFunction, this, placeholders::_1);
    func(6);
}

And you created a MyClass instance:

MyClass instance;

Then 6 will be printed to stdout.

Upvotes: 3

Related Questions