germannp
germannp

Reputation: 197

C++ function accepting function pointer and non-static member function as parameter

I built an interface taking pointers to functions. Sometimes this calculation depends on state, which I want to encapsulate in a class and pass its method:

#include <iostream>


class Printer {
public:
    static void print(int i) {  // Want to get rid of the static
        std::cout << i << "\n";
    }
};


template<typename int_func>
void with_1(int_func func) {
    func(1);
}


int main(int argc, char const *argv[]) {
    Printer printer;
    with_1(printer.print);
    return 0;
}

I need non-static methods (and would even prefer overloading operator()). However removing the static results in error: a pointer to a bound function may only be used to call the function.

I could use a dummy like this:

Printer printer;
void dummy(int i) {
    printer.print(i);
}


int main(int argc, char const *argv[]) {
    with_1(dummy);
    return 0;
}

But that does not look elegant to me. Can I write a template that accepts both, function pointers and non-static methods? Or is there even a better design pattern for my problem?

Upvotes: 0

Views: 128

Answers (2)

Garf365
Garf365

Reputation: 3706

You can not simply pass non-static method like this, because they work on instance. A simply solution is to use lambda:

#include <iostream>


class Printer {
public:
    static void print(int i) {  // Want to get rid of the static
        std::cout << i << "\n";
    }
};


template<typename int_func>
void with_1(int_func func) {
    func(1);
}


int main(int argc, char const *argv[]) {
    Printer printer;

    // Can use capture by reference because we are sure printer still
    // exist during execution of with_1
    with_1([&printer](int i){ printer.print(i); });

    return 0;
}

example

Upvotes: 1

lorro
lorro

Reputation: 10880

Try this:

int main(int argc, char const *argv[]) {
    Printer printer;
    with_1( std::bind( &Printer::print, printer, std::placeholders::_1 ) );
    return 0;
}

(You'll need to #include <functional>.)

Upvotes: 1

Related Questions