Оператор в качестве параметра шаблона

Возможно ли это?

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

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

Если нет, это способ добиться этого без ifs и switch?

Ответы

Ответ 1

Для этого вы можете использовать функторы:

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

Calc<std::plus<int>>(5, 3);

Ответ 2

Нет - шаблоны относятся к типам или примитивным значениям.

Вы можете без проблем передавать так называемые функциональные объекты, которые можно назвать подобными функциями и нести желаемую функциональность оператора (несмотря на хороший синтаксис).

Стандартная библиотека определяет несколько, например. std::plus для добавления...

#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());
}

Ответ 3

Вы можете сделать это, используя полиморфизм:

#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;
}

Ответ 4

Если вы ссылаетесь на глобальных операторов, вы уже получили ответы. Однако в некоторых частных случаях было бы полезно использовать перегруженные функции оператора.

Это может быть тривиально; тем не менее это может быть полезно в некоторых случаях, поэтому я отправляю один пример:

#include <iostream>

template<typename opType, typename T>
int operation(opType op, T a, T b)
{
    return (a.*op)(1) + (b.*op)(1);
}

struct linear
{
    int operator()(int n) const {return n;}
    int operator[](int n) const {return n * 10;}
};

int main()
{
    linear a, b;

    std::cout << operation(&linear::operator(), a, b) << std::endl
        << operation(&linear::operator[], a, b);

    return 0;
}

выход:

2
20