2010-09-17 12 views
15

Est-ce possible?opérateur comme paramètre de modèle

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

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

Si ce n'est pas le cas, comment y parvenir sans ifs et sans commutateurs?

+0

(int a, b) -> (int a, int b). http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=141 – DumbCoder

Répondre

16

Vous pouvez utiliser foncteurs pour cela:

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

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

Cela devrait être le chemin à parcourir. Merci beaucoup. – Xirdus

+3

@xir: Notez que le passer comme un argument de fonction au lieu d'un argument de modèle comme Dario montre donne à l'utilisateur plus de liberté, par ex. pour passer les foncteurs à état, 'bind()' expressions, ... –

+0

Pourrait juste être 'return Op() (a, b);', mais comme Georg dit qu'il est plus flexible si vous l'acceptez comme un paramètre. – GManNickG

16

Non - modèles sont sur types ou valeurs primitives.

Vous pouvez néanmoins passer des objets fonction qui peuvent être appelés comme des fonctions et porter la fonctionnalité d'opérateur désirée (malgré une bonne syntaxe).

La bibliothèque standard définit plusieurs bibliothèques, par ex. std::plus pour 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

Vous pouvez le faire en utilisant le polymorphisme:

#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

Correct. Mais pour montrer que c'est vraiment utile, vous devrez utiliser le polymorphisme d'exécution et utiliser une interface 'Operator &'. Implémentez 'Calc' d'ailleurs. Nontheless +1 à l'avance! – Dario

0

Si vous faites référence aux opérateurs globaux, vous avez déjà reçu quelques réponses. Dans certains cas, cependant, il peut être utile d'utiliser des fonctions d'opérateur surchargées.

Cela peut être trivial; Néanmoins, il pourrait être utile dans certains cas, ce qui est la raison pour laquelle je poste un exemple:

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

sortie:

2 
20