1

I want to be able to call a member function (eg. doSomething() in class testClass ) outside the class using some sort of functional template. In short, be able to call a non-static member function somewhat in this manner, functionCaller(t.doSomething) from main().

Say I have a C++ class like:

class testClass {
public:
    testClass()
    {
        value = 0;
    }
    int prod(int i)
    {
        value *= i;
        return value;
    }
    int doSomething()
    {
        value = prod(10);
        return value;
    }

private:
    int value;
};

My functional template looks something like this:

template<typename T, typename ret>
ret callFunction(T t, ret (T::*func)()) {

    // checkSomePermissionsHere()
    return t.func()
}

If I try to use this template in the following manner:

int main()
{
    testClass t1;
    callFunction(t1, &testClass::doSomething);
    return 0;
}

I get this error:

error: no member named 'func' in 'testClass'
return t.func(a);
         ^

What is the correct way to call this member function (doSomething) on object t1 through the callFunction method? I want to implement callFunction as part of a general API which does some checks before executing the provided fucntion.

I'm using clang/LLVM 3.5 for my compiler.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Adwait Dongare
  • 301
  • 1
  • 3
  • 13

1 Answers1

3

Change this:

return t.func()

to this:

return (t.*func)();

and it should compile and execute fine.


As Joachim Pileborg stated, you could use std::function and std::bind. In that case, your code could look like this:

#include <functional>
#include <iostream>

class EventHandler
{
    public:
        void addHandler(std::function<void()> callback)
        {
            std::cout << "Handler added..." << std::endl;
            // Let's pretend an event just occured
            callback();
        }
};

class testClass {
public:
    testClass()
    {
        value = 0;
        EventHandler handler;
        handler.addHandler(std::bind(&testClass::doSomething, this));
    }
    int doSomething()
    {
        value = prod(10);
        std::cout << "I did something!\n";
        return value;
    }

private:
    int value;
};

int main()
{
    testClass t1;
    return 0;
}

The code above was based on this answer.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    I'm not sure I have access to functional. Do you know if clang 3.5 supports it yet? Otherwise std::functon would have been a good idea. Thank for the suggestion. EDIT: I see it has been supported for some time now – Adwait Dongare Aug 18 '15 at 18:37
  • Thank you for letting us know @AdwaitDongare! – gsamaras Aug 19 '15 at 06:41