2

I've written a simplified version of my code, to illustrate my problem. In my program alot of other stuff is in the code, that's why I need to have some functions in a class. I don't know how to define the parameters so that the f2 of foo is finally called.

I can have f0 inside of testClass if it's the only way of solving the problem, but I don't know how to write that either.

#include <iostream>
using namespace std;

class testClass {
public:
    void f1();
    void f2(int i);

} foo;

void f0(void (*f)(int)) {
    (*f)(1337); // f = a pointer to f2, which is sent from f1
}

void testClass::f2(int i) {
    cout << i;
}

void testClass::f1() {
    f0(&f2);
}

int i;
int main() {
    foo.f1(); // I want foo.f1 to call f0 which should call foo.f2()
    cin >> i;
}

If I were to remove both testClass:: and foo., it will work. But since I can't do that, how should I correctly define the parameter in f0? And how should I correctly call f0 inside of f1?

Please help!

4
  • Thanks for all the anwers (feel free to add more), I'm going to use Mats solution for now, since I've not learn all the details about the functions in the other solutions. But I don't know which one is the most performence cheap (I'm writing a chess engine), so if you have an answer on that question please tell me here. :) Commented Feb 7, 2015 at 22:47
  • Side note: declare variables where they're used and certainly don't use globals for no apparent reason Commented Feb 7, 2015 at 22:50
  • I'm using huge trees of recursive functions, do you suggest I still should use temporary defined variables or could global variables perform better? Commented Feb 7, 2015 at 23:15
  • 1
    What do the variables have to with "trees of recursive functions". You mean you pass state around a lot? Especially then. You will not be able to cope with the complexity/make it testable. Commented Feb 7, 2015 at 23:18

4 Answers 4

1

Non-static member functions need a "this" object to be called on, they can't be called like top-level, or static member, functions. So you'll need an extra parameter for f0, and adapt your syntax to for member function calls.

void f0(testClass *obj, void (testClass::*f)(int)) {
  (obj->*f)(1337);
}

Change f1 to also pass this.

void testClass::f1() {
    f0(this, &testClass::f2);
}
Sign up to request clarification or add additional context in comments.

2 Comments

If I were to put f0 inside of testClass, could I avoid this problem then?
If you put f0 inside your testClass, then you no longer need to pass this around.
1

First of all, here , it seems you go all the way just to verbosely say

returnValue someClass::f1{
f2(1337)
}

Second of all , if you still need (for some reason) to implement it this way, I suggest using templates :

template <Class T>
void f0 (T pointerToTFunction){
pointerToTFunction(1335)l
}

class testClass{

void testClass::f2(int i) {
    cout << i;
}

void testClass::f1() {
    f0<void(*testClass::A)(int)>(&testClass::f2);
}

}

Comments

1

C++11, templates and lambdas.

#include <iostream>
using namespace std;

class testClass {
public:
   void f1();
   void f2(int i);
} foo;

template <class F>
void f0(F&& f)
{
    f(1337);
}

void testClass::f2(int i) {
   cout << i;
}

void testClass::f1() {
   f0([&](int x){f2(x);});
}

int i = 1;
int main() {
   foo.f1();
}

Comments

1

Use std::function for this, or template everything and use std::bind.

http://en.cppreference.com/w/cpp/utility/functional/function

You need the bind anyways to adapt the member function to the void(int) signature anyways:

Live On Coliru

#include <iostream>
#include <functional>
using namespace std;

typedef std::function<void(int)> F;

class testClass {
public:
    void f1();
    void f2(int i);

} foo;

void f0(F f) {
    (f)(1337); // f = a pointer to f2, which is sent from f1
}

void testClass::f2(int i) {
    cout << i;
}

void testClass::f1() {
    f0(std::bind(&testClass::f2, this, std::placeholders::_1));
}

int main() {
    foo.f1(); // I want foo.f1 to call f0 which should call foo.f1()
    int i;
    cin >> i;
}

If you decide you want to have more performance, and don't mind implied header-implemented functions:

Live On Coliru

template <typename F>
void f0(F f) {
    (f)(1337); // f = a pointer to f2, which is sent from f1
}

1 Comment

Added a hint on the template approach (Live On Coliru](coliru.stacked-crooked.com/a/42306c4c0f6fab4d))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.