2010-09-17 28 views
15

Czy to możliwe?operator jako parametr szablonu

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

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

Jeśli nie, czy można to osiągnąć bez elementów ifs i switch?

+0

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

Odpowiedz

16

Można użyć do tego funktory:

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

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

To powinna być droga. Wielkie dzięki. – Xirdus

+3

@xir: Należy zauważyć, że przekazywanie go jako argumentu funkcji, a nie jako argumentu szablonu, takiego jak programy Dario, daje użytkownikowi większą swobodę, np. do przekazywania funktorów stanowych, wyrażeń 'bind()', ... –

+0

Może to być 'return Op() (a, b);', ale jak Georg mówi, jest bardziej elastyczny, jeśli przyjmiesz go jako parametr. – GManNickG

16

Brak - szablony około rodzaje lub wartości prymitywne.

Mimo to można przejść przez obiekty o nazwach , które można nazwać funkcjami i przenieść pożądaną funkcjonalność operatora (pomimo dobrej składni).

Standardowa biblioteka definiuje kilka, np. std::plus dodawania ...

#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

Można to zrobić za pomocą polimorfizmu:

#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

Prawidłowo. Ale pokazanie tego jest naprawdę użyteczne, będziesz musiał użyć polimorfizmu środowiska wykonawczego i użyć interfejsu 'Operator &'. Wdrożyć 'Calc' w tej sprawie. Niemniej jednak z wyprzedzeniem +1! – Dario

0

Jeśli odnieść się do operatorów globalnych, już otrzymał kilka odpowiedzi. Jednak w niektórych szczególnych przypadkach pomocne może być użycie przeciążonych funkcji operatora.

To może być banalne; Niemniej jednak może to być pomocne w niektórych przypadkach, dlatego mogę napisać jeden przykład:

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

wyjściowa:

2 
20 
Powiązane problemy