+8  A: 

You can have pointers to functions as template parameters, but function objects are more "C++ish". However, you can write your function template in a way that accepts both variants:

#include <iostream>

void f(int x)
{
    std::cout << "inside function f\n";
}

struct g
{
    void operator()(int x)
    {
        std::cout << "inside function object g\n";
    }
};

template <typename Functor>
void do_work(Functor fun)
{
    fun(42);
}

int main()
{
    // template argument is automatically deduced
    do_work(&f);
    // but we could also specify it explicitly
    do_work<void(*)(int)>(&f);

    // template argument is automatically deduced
    do_work(g());
    // but we could also specify it explicitly
    do_work<g>(g());
}

Here, the name Functor hints at any type that is callable via f(x) syntax. Functions support this syntax naturally, and in the case of function objects, f(x) is syntactic sugar for f.operator()(x).

FredOverflow
+1 ...and they compile to a direct call, without function-pointer calling overhead at runtime.
Doug
@Doug: that's not guaranteed. Highly likely, though, since e.g. `std::sort` benefits a lot from that optimization.
MSalters
Your implementation there will match the `typename Fun` parameter to the function prototype `void(*)(int)`, and then use the same instantiation for both calls - not inlining: that's why you actually end up passing the function pointer as a run-time argument to `do_work(Fun fun)`.
Tony
-1 : the code you show does not even need the template part, as it just passes a function pointer as argument (with same signature) as Tony points out in the comment above.
Martin
+1 - does not deserve -1: But it *could* accept a function object just fine; this is the flexible, standard approach to use.
Eamon Nerbonne
@MSalters - definitely not guaranteed. I misread the FredOverflow's answer slightly - I thought FredOverflow had `do_work` accepting a template non-type function pointer argument, as the question indicates, rather than a template type argument. The non-type arguments are even more likely to compile into a direct call.
Doug
@Martin: I have updated my answer, would you reconsider the downvote?
FredOverflow
@Fred: removed downvote
Martin
+5  A: 

No, you need to wrap the functions in a wrapper class with operator(). Here is an example:

class Functor_f
{
public:
    void operator()(int x)
    {
    }
};

class Functor_g
{
    public:
    void operator()(int x)
    {
    }
};



template<typename F>
void do_work()
{
  F f;
 int v = calculate();
  f(v);
}


int main()
{
    do_work<Functor_f>();
    do_work<Functor_g>();

}

You can use std::ptr_fun to do this wrapping automatically for you. For example:

void f(int x)
{
}

void g(int x)
{
}

template<typename F>
void do_work(F f)
{
 int v = calculate();
  f(v);
}


int main()
{
    do_work(std::ptr_fun(f));
    do_work(std::ptr_fun(g));

}
Naveen
The first example (without `std::ptr_fun`) gives a much better chance of actual inlining -- and (although of course it depends on a lot) is thus most likely fastest, somewhat counter-intuitive perhaps. Cheers,
Alf P. Steinbach
+15  A: 

Your idea's ok, but you're not passing in a type but a value (specifically, a function pointer>. Alternatively, pass a template policy providing functions - it's a good idea to read Modern C++ Design by Andrei Alexandrescu.

#include <iostream>

int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }

typedef int (*F)(int);

template<F f> 
int do_work() 
{ 
    return f(7);
} 

int main()
{
    std::cout << do_work<f>() << '\n'
              << do_work<g>() << '\n'; 
}

OR

int calculate() { return 4; }

struct F { int do_something_with(int x) { return 2 * x; } };
struct G { int do_something_with(int x) { return -3 * x; } };
// or, make these functions static and use Operator::do_something_with() below...

template<typename Operation> 
int do_work() 
{ 
    int v = calculate(7);
    return Operation().do_something_with(v);
} 

int main()
{
    std::cout << do_work<F>() << '\n'
              << do_work<G>() << '\n'; 
}
Tony
Martin
@Martin: it's a crucial question - all up the optimiser. I wouldn't bet on this being inlined, whereas I would bet on a policy template member....
Tony
@Tony - could you maybe link in some resource that (approx.) describes a template policy thing in the way you would adopt it for this problem?
Martin
`return Operation(7);` should be `return Operation()(7);`
Eamon Nerbonne
+1; Just like Martin asked, it would be great to have your implementation of the policy template member. I'm still struggling with much of the "C++ Modern Design" book which I don't really grasp. Any concrete application example is dearly welcome.
Stephane Rolland
@Martin: I changed the template policy version above a little to more directly mirror the question. While it is a little more verbose, I tend to use function names for the things the policy provides - it is common for there to be more than one function in each policy, and it often makes for more comprehensible code. , @Stephane Rolland: for a more great concrete application, consider `std::sort`'s acceptance of a less-than policy... by not hard-coding operator<, it allows you to say compare dereferenced pointers or reverse the sort order. Is that a useful practical example?
Tony
+1  A: 

One approach that is highly likely to generate the direct function call, because it gives the compiler no option, is to use a static member function:

struct F { static void func(int x) { /*whatever*/ } };
struct G { static void func(int x) { /*whatever*/ } };

template<class T>
void do_work() {
    T::func(calculate());
}

No function pointers, no temporaries, and no unnecessary this. I guarantee nothing, of course, but generated code should be reasonable even with optimization disabled.

brone
+1 : very nice solution. Not applicable in the problem that backs my question, but very nice as a general solution!
Martin