views:

93

answers:

3

Is it possible?

template<operator Op> int Calc(int a, b)
{ return a Op b; }

int main()
{ cout << Calc<+>(5,3); }

If not, is way to achieve this without ifs and switches?

+4  A: 

You could use functors for this:

template<typename Op> int Calc(int a, int b)
{
    Op o;
    return o(a, b);
}

Calc<std::plus<int>>(5, 3);
Nikola Smiljanić
It should be the way to go. Thanks a lot.
Xirdus
@xir: Note that passing it as a function argument instead of as a template argument like Dario shows gives the user more freedom, e.g. to pass stateful functors, `bind()` expressions, ...
Georg Fritzsche
Could just be `return Op()(a, b);`, but like Georg says it's more flexible if you accept it as a parameter.
GMan
This is the first thing that came to my mind :)
Nikola Smiljanić
+12  A: 

No - templates are about types or primitive values.

You can nontheless pass so called function objects that can be called like functions and carry the desired operator functionality (despite having a nice syntax).

The standard library defines several ones, e.g. std::plus for addition ...

#include <functional>

template<typename Op>
int Calc(int a, int b, Op f) { 
  return f(a, b);
}

int main() { 
  cout << Calc(5,3, std::plus());
  cout << Calc(5,3, std::minus());
}
Dario
+1  A: 

You can do this using polymorphism:

#include <cstdlib>
#include <iostream>
using namespace std;


class Operator
{
public:
    virtual int operator()(int a, int b) const = 0;
};

class Add : public Operator
{
public:
    int operator()(int a, int b) const
    {
        return a+b;
    }
};

class Sub : public Operator
{
public:
    int operator()(int a, int b) const
    {
        return a-b;
    }
};

class Mul : public Operator
{
public:
    int operator()(int a, int b) const
    {
        return a*b;
    }
};


int main()
{
    Add adder;
    cout << adder(1,2) << endl;
    Sub suber;
    cout << suber(1,2) << endl;
    Mul muler;
    cout << muler(1,2) << endl;
    return 0;
}
John Dibling
Dario