I often find myself wishing there was a generalized way of calling functions and function-like “things”.

Functors are obviously quite function-like. Member function pointers can be treated like function where the object pointer as just another parameter. Member object pointers can be treated like a function which retrieves a member from a pointed object.

Now with the new c++11 standard, it is possible to do this quite easily!

#include <type_traits>
#include <utility>

// functions, functors, lambdas, etc.
template<
    class F, class... Args,
    class = typename std::enable_if<!std::is_member_function_pointer<F>::value>::type,
    class = typename std::enable_if<!std::is_member_object_pointer<F>::value>::type
    >
auto eval(F&& f, Args&&... args) -> decltype(f(std::forward<Args>(args)...))
{
    return f(std::forward<Args>(args)...);
}

// const member function
template<class R, class C, class... Args>
auto eval(R(C::*f)() const, const C& c, Args&&... args) -> R
{
    return (c.*f)(std::forward<Args>(args)...);
}

template<class R, class C, class... Args>
auto eval(R(C::*f)() const, C& c, Args&&... args) -> R
{
    return (c.*f)(std::forward<Args>(args)...);
}

// non-const member function
template<class R, class C, class... Args>
auto eval(R(C::*f)(), C& c, Args&&... args) -> R
{
    return (c.*f)(std::forward<Args>(args)...);
}

// member object
template<class R, class C>
auto eval(R(C::*m), const C& c) -> const R&
{
    return c.*m;
}

template<class R, class C>
auto eval(R(C::*m), C& c) -> R&
{
    return c.*m;
}

The first overload of eval covers almost every single case. Furthermore, note the use of universal references and forwarding which automatically handles const and reference qualifiers.

The next three overloads handle const and non-const member function pointers. Additional parameters of C& are added as if they were parameters of the original functions.

Member object pointers are then treated as functions which take a reference to an object then return a reference to its member.

The use of std::enable_if prevents the first overload from greedily instantiating for member function pointers.

Now to show it in action:

#include <iostream>

struct Bloop
{
    int a = 10;
    int operator()(){return a;}
    int operator()(int n){return a+n;}
    int triple(){return a*3;}
};

int add_one(int n)
{
    return n+1;
}

int main()
{
    Bloop bloop;

    // free function
    std::cout << eval(add_one,0) << "\n";

    // lambda function
    std::cout << eval([](int n){return n+1;},1) << "\n";

    // functor
    std::cout << eval(bloop) << "\n";
    std::cout << eval(bloop,4) << "\n";

    // member function
    std::cout << eval(&Bloop::triple,bloop) << "\n";

    // member object
    eval(&Bloop::a,&bloop)++; // increment a by reference
    std::cout << eval(&Bloop::a,bloop) << "\n";

    return 0;
}

Which gives the expected output:

1
2
10
14
30
11

Note: Be careful with pointers to overloaded functions, the compiler will not be able to determine which overload to use. You will need to either explicitly cast to a function pointer or std::function object with the desired type.

Edit: Thank you to STL for pointing out member object pointers should return references, not values.

Edit2: Thanks to Aaron McDaid for pointing out a few more mistakes.