оператор в качестве параметра шаблона - PullRequest
18 голосов
/ 17 сентября 2010

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

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

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

Если нет, то есть ли способ добиться этого без ifs и переключателей?

Ответы [ 5 ]

19 голосов
/ 17 сентября 2010

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

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

Calc<std::plus<int>>(5, 3);
17 голосов
/ 17 сентября 2010

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

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

Стандартная библиотека определяет несколько, например, 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());
}
2 голосов
/ 17 сентября 2010

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

#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;
}
0 голосов
/ 21 марта 2018

Используйте

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{});
}

если Дарио не ответит error: cannot deduce template arguments for ‘plus’ from ()

0 голосов
/ 06 декабря 2016

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

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

#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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...