2016-03-28 71 views
5

In Python, abbiamo una semplice sintassi semplice per assumere un int/float arbitrario a una potenza. Vale a dire, per voi non-Python programmatori, possiamo avere la seguente dichiarazione:Sovraccarico ** in C++

y = 2 ** 3 
print y 

Questo stamperà 8 alla console, e ha la sintassi bello come c'è una costruito in operatore di "potere". È possibile sovraccaricare "**" come un singolo operatore in C++? In particolare, voglio realizzare qualcosa di simile:

int a = 2; 
int b = 3; 
cout << (a**b) << endl; 

o, se ciò non fosse possibile, qualcosa di simile:

MyInt a = new MyInt(2); // Wrapper class around ints to play nicely with ** 
MyInt b = new MyInt(3); 
cout << (a**b) << end; // Assume ostream overridden for MyInt 

Questi dovrebbe anche stampare da 8 a console. Capisco che sarebbe molto più facile ignorare l'operatore "^" per fare la stessa cosa, ma sono principalmente interessato a vedere se posso sovraccaricare "**". L'operatore "*" (per il caso della classe MyInt, se fosse una funzione membro) deve cercare se l'argomento è un altro "*", in quanto non conosco un modo per specificare "**" come un solo operatore? È persino possibile passare un operatore come argomento?

Accordo aggiuntivo/bonus se possibile (come se non l'avessi già detto abbastanza): No macro !!!

+2

Si chiama overloading degli operatori, perché sovraccarichi gli operatori. ** non è un operatore. – DeiDei

+1

Non sovraccaricare l'operatore^in termini di potenza, ha una precedenza inferiore a ==, + o - quindi causerà molte sorprese. –

+0

@ ÖöTiib Ottimo punto! – mwm314

risposta

4

Vuoi dire qualcosa del genere?

#include <iostream> 
#include <cmath> 

struct MyInt { 
    int val; 
    struct MyProxy { int val; }; 

    MyProxy operator *() const{ return MyProxy{val}; } 
    MyInt operator * (const MyProxy& b) { return MyInt{ static_cast<int>(std::pow(val, b.val)) }; } 

}; 

std::ostream& operator << (std::ostream& o, const MyInt& m) { return o << m.val; } 

int main(){ 
    MyInt a{5}, b{3}; 
    std::cout << a**b << std::endl; 
} 

vederla dal vivo qui http://coliru.stacked-crooked.com/a/ab56b9cd6e422e12

Spiegazione:

  1. sovraccaricare l'unario * all'operatore di restituire un oggetto proxy
  2. sovraccaricare il binario * all'operatore di utilizzare il proxy ... Semplice :-)
  3. Ho usato una classe proxy per evitare bug sottili ..

C++ è divertente ... Voglio credere che si sta facendo questo per divertimento e non nella produzione ... Causa la sua una pessima idea in produzione, basta chiamare std::pow

+1

Solo perché qualcosa è possibile, non significa che sia una buona idea ... –

+2

Sì ... Lo so :-) ... Voglio credere che l'OP vuole farlo per divertimento, non nel codice di produzione – WhiZTiM

+0

Giusto per essere chiari ed espliciti: questo può essere un piccolo gioco divertente da giocare (e lo ammetto apertamente, l'ho fatto da solo, e mi è piaciuto), ma ** non lo faccio ** nel codice di produzione o qualsiasi altra cosa tranne il codice puramente usa e getta, scritto solo per il piacere di giocare. –

4

Risposta breve: No. Non c'è modo di "sovraccaricare" sequenze di caratteri/token arbitrari in C++. risposta

più lunga:a**b è equivalente a a * (*b), in modo da poteva sovraccarico sia binario * (cioè moltiplicazione) e unario * (cioè dereference) in qualche modo grossolano. Ma questo sarebbe completamente opaco/inaspettato per chiunque legga il tuo codice, e doloroso per il debug/manutentore in futuro.

Basta scrivere una funzione denominata pow()!

+0

Questo è un trucco molto sporco. – mwm314

+0

Suppongo che non sia possibile passare un operatore come argomento? – mwm314