From the views of things, you really want to pass an action that should be called as a template parameter to an external function that calls an indirect call. Depending on your point of view, this can be thought of as a policy class or as an instance of strategy template 1 .
Since templates are mostly type-based, you usually want to do this with classes, not functions. Other than that, it's quite simple, although there are several different possible approaches.
One approach would be to force calc to invoke the specified policy in response to its called operator() . The code for this will look like this:
The code to use might look something like this:
int main() { auto x=calc<add>()(1,2); auto z=calc<sub>()(2,1); }
Another possibility would be for calc perform the calculation when building the object and return the result on request. This avoids (among other things) an additional set of partners for creating the object, and then call its operator() to perform the calculation. On the other hand, this means adding an implicit conversion operator from the calculation object to return the result of the calculation, which many people don't like. The code following this route may look like this:
template<class C> struct calc2 { int val; public: calc2(int a, int b) : val(C()(a, b)) {} operator int() { return val; } }; // ... std::cout << calc2<add>(1, 2) << "\n"; std::cout << calc2<sub>(2, 1) << "\n";
Itโs a little difficult to say what is really preferable between these two options (and there are other options). Between them, the choice is mainly between an ugly challenge and an ugly implicit transformation.
Of course, depending on what you do in the โstrategicโ part of things, the solution may be simple: if you really need to perform the action only on demand, and not immediately after creation (and save only the result until it is needed ), the second option is not an option at all.
I must add that I assume that the integer that you are currently using to determine which operation should be used was a random side effect of the implementation that you figured out. In other words, I assume that specifying the operation itself directly, as I did above, is really preferable.
<sub> 1. Strategy is usually a whole algorithm, and not something as trivial as adding versus subtraction, but I assume that only an example, and your real application does something more significant. Sub>