2010-09-17 3 views
15

Возможно ли это?оператор как параметр шаблона

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

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

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

+0

(ИНТ а, б) -> (Int А, внутр б). http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=141 – DumbCoder

ответ

16

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

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

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

Это должен быть путь. Большое спасибо. – Xirdus

+3

@xir: Обратите внимание, что передача его в качестве аргумента функции вместо аргумента шаблона, такого как показания Dario, дает пользователю больше свободы, например. чтобы передать функторы stateful, 'bind()' выражения, ... –

+0

Может быть просто 'return Op() (a, b);', но, как говорит Георг, он более гибкий, если вы принимаете его как параметр. – GManNickG

16

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

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

Стандартная библиотека определяет несколько, например. 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

Вы можете сделать это с помощью полиморфизма:

#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

Исправить. Но показать это действительно полезно, вам нужно будет использовать полиморфизм времени выполнения и использовать интерфейс 'Operator & '. Внесите 'Calc', если на то пошло. Тем не менее +1 заранее! – Dario

0

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

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

#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 
Смежные вопросы