1
   class manip{
public:
    int t;
    manip(int tom){
        t = tom;
    }
    int sub(int val){
        return t - val;
    }
    int add(int val){
        return t + val;
    }
    int perform(int(manip::*key)(int), int val){
        return (this->*key)(val);
    }
};

int main() {
    manip g(5);
    cout << g.perform(&manip::add, 9) << ":" << g.perform(&manip::sub, 9);

(This is just a simplified version of a problem im trying to solve in a larger piece of code)

the problem lies here

    int(b::*func)(int) = b::add;

    int c = func(2);

this gives me a syntax error on the second line (because i have no reference to the "this" data). How do i change it so that the function being called isnt b::add but rather inst.add.

Edit : Posted a working version of the code. Thanks Speed8ump

Arhowk
  • 901
  • 4
  • 11
  • 22
  • Possible duplicate http://stackoverflow.com/questions/14189440/c-class-member-callback-simple-examples/14189561#14189561 – Miguel Jan 05 '14 at 02:39
  • Suggestion to use the [`std::mem_fn`](http://en.cppreference.com/w/cpp/utility/functional/mem_fn) helper to get a `std::function` pointing to the member function. As we're in C++ we should avoid C style function pointers. – Mgetz Jan 05 '14 at 02:51
  • I'm just learning CPP so I'm not terribly experienced, but std::mem_fn looks like it might be what I'm looking for, ill play with it. The only issue is that it looks ugly to use std::mem_fn every time performOperation is called, is there a way to use std::mem_fn inside performOperation? – Arhowk Jan 05 '14 at 03:18
  • You have a syntax error, you need to use `... = &b::add;`. – Mark Ransom Jan 05 '14 at 05:32
  • no the issue is b::add is nonstatic – Arhowk Jan 05 '14 at 05:34

3 Answers3

2

in your example 'func' is a member function pointer. It must be used on an instance of the data type it is a member of:

int c = (inst.*func)(2);
Speed8ump
  • 1,307
  • 10
  • 25
  • This... seemed to work just fine... Not sure why people keep barking about callbacks, passer functions, etc... I'm going to bed ATM but if noone posts a good reason not to use it (I assume there is one if people are going through so much effort not to use this) i'll best answer it. – Arhowk Jan 05 '14 at 05:41
1

You need to give a parameter pointing to the struct (or aA).

int main(){
    b inst(5)
    int(b::*func)(int, struct b*) = b::add;
    int c = func(2, &inst);
}

int add(int a, struct b* ptr){
    return a + ptr->aA;
}
user1610743
  • 840
  • 8
  • 24
  • In the actual code, there will be alot of decently long functions that I want to swap out and making nonstatic versions of each function isn't viable – Arhowk Jan 05 '14 at 03:16
  • For what purpose do you try to avoid memberfunctions ? If its performance you should know that using function pointers will likely make it even worse performancewise than using a member function. This is because processors are designed to support fast member functions. – user1610743 Jan 05 '14 at 03:47
  • As stated, runtime there will be alot of functions with a decent amount of head so I'd rather stay away from it, it's also just to keep the code alot neater for my own eyes (I come from java and C++ to me is just so... bleh) – Arhowk Jan 05 '14 at 05:03
  • For me, using classes with member function would look smoothest. Its a hell easier to understand whats going on, when u need to debug something one day. – user1610743 Jan 05 '14 at 06:22
1

If your compiler is new enough you can avoid function pointers and use std::function instead

 int(b::*func)(int) = b::add;

becomes

#include <functional>
#include <iostream>
 class manip{
public:
    int t;
    manip(int tom){
        t = tom;
    }
    int sub(int val){
        return t - val;
    }
    int add(int val){
        return t + val;
    }
    int perform(std::function<int(manip*,int)>f, int val){
        return f(this, val);
    }
};

int main() {
    manip g(5);
    std::cout << g.perform(&manip::add, 9) << ":" << g.perform(&manip::sub, 9);
}
Zeks
  • 2,265
  • 20
  • 32
  • see my comment on user1610743 about the second one, first one's a bit too confusing for me – Arhowk Jan 05 '14 at 05:36
  • I think we really need a bit more context on how do you plan to use the code in real app. – Zeks Jan 05 '14 at 05:44
  • I guess a key componet of the question I didn't clearly state is that the function using the function argument will use itself as the instance parameter – Arhowk Jan 05 '14 at 18:03
  • I have updated my answer to match your edits. The only change necessary is the signature and body of perform() operation. Although to be honest your code _still_ looks strange. I have a feeling you are doing something very wrong here – Zeks Jan 05 '14 at 19:46
  • I suspect it is the result of you trying to write java style code in C++. We would be able to help better if you give us a more specific example of a real problem you are trying to solve – Zeks Jan 05 '14 at 19:53