Lorah Attkins
Lorah Attkins

Reputation: 5856

Dispatch for binary and unary callables in C++03

I'm having troubles implementing this in legacy C++, but I'm pretty sure it can be done. Say I have a higher order function that needs two versions, one for unary callables (function objects, functions, member functions)

template <class F>
void ho_fun(F argFun) { 
    int arg1; 
    argFun(arg1); 
}

and one for binary:

template <class F>
void ho_fun(F argFun) { 
    int arg1, arg2; 
    argFun(arg1, arg2); 
}

I'm looking for a complete solution in terms of "callable type" (otherwise I'd obviously use arity from function traits for this) i.e. support for functions and function objects.

I'm translating this lovely post to C++03 (remove ... and using typedefs) but it doesn't seem to work.

PS. I'm not solving the particular problem listed above, that's just the sscce. Also I mention C++03 because I'm working on legacy code for this project and a modern solution is of no use to me. By all means feel free to post a modern one but please consider helping me as well.

Upvotes: 3

Views: 113

Answers (1)

Jonathan Mee
Jonathan Mee

Reputation: 38919

This answer provides a solution to the question I understand you to be asking:

How can I specialize a function so that it can detect whether it's argument is a unary or binary function, method, or functor?

In your only option is to write specializations for each of these, and incidentally you'll need to make specializations for const methods as well as non-const methods:

template <typename Arg, typename Result>
void ho_fun(Result(*argFun)(Arg)) {
    Arg arg = 13;

    argFun(arg);
}

template <typename Arg1, typename Arg2, typename Result>
void ho_fun(Result (*argFun)(Arg1, Arg2)) {
    Arg1 arg1 = 13;
    Arg2 arg2 = 42;

    argFun(arg1, arg2);
}

template <typename T, typename Arg, typename Result>
void ho_fun(Result(T::*argFun)(Arg)) {
    T myClass;
    Arg arg = 13;

    (myClass.*argFun)(arg);
}

template <typename T, typename Arg1, typename Arg2, typename Result>
void ho_fun(Result(T::*argFun)(Arg1, Arg2)) {
    T myClass;
    Arg1 arg1 = 13;
    Arg2 arg2 = 42;

    (myClass.*argFun)(arg1, arg2);
}

template <typename T, typename Arg, typename Result>
void ho_fun(Result(T::*argFun)(Arg) const) {
    T myClass;
    Arg arg = 13;

    (myClass.*argFun)(arg);
}

template <typename T, typename Arg1, typename Arg2, typename Result>
void ho_fun(Result(T::*argFun)(Arg1, Arg2) const) {
    T myClass;
    Arg1 arg1 = 13;
    Arg2 arg2 = 42;

    (myClass.*argFun)(arg1, arg2);
}

template <class T>
void ho_fun(T argFun) {
    ho_fun(&T::operator());
}

Live Example

Upvotes: 2

Related Questions