2015-09-16 29 views
12

Ho una classe Rectangle con operatori di conversione sia double e std::string:uso non chiara dell'operatore doppio()

class Rectangle 
{ 
public: 
    Rectangle(double x, double y) : _x(x), _y(y) {} 
    operator std::string(); 
    operator double(); 
private: 
    double _x, _y; 
    double getArea() {return _x * _y;} 
}; 

int main() 
{ 
    Rectangle r(3, 2.5); 
    cout << r << endl; 
    return 0; 
} 

Non capisco il motivo per cui operator double() viene invocato, piuttosto che operator std::string(). Per quanto ne so, in base a C++ wikibook, operator double viene utilizzato per convertire gli oggetti Rectangle in double.

Quindi cosa sta succedendo qui? È legato al fatto che un int viene passato al costruttore? Se è così, perché?

+0

Che cosa significa anche convertire un rettangolo in un doppio. –

+0

immagino (doppio) o altro –

+2

@AlexGoft No, l'altro Alex intendeva "cosa significa * logicamente *?". A prima vista, l'operazione sembra priva di significato. –

risposta

11

Non si dispone di un operatore per inviare il rettangolo allo stream. cout ha un sovraccarico che accetta uno double e la classe può essere convertita implicitamente in un double in modo che venga scelto.

La ragione del sovraccarico stringa non è selezionato e non è considerato come un'ambiguità perché operator << per una stringa è una funzione membro e non è incluso nel member overload e non member overload insieme di cout. Se commentiamo il operator double possiamo vedere we get a compiler error.

Se si desidera chiamare operator string, è necessario eseguire il cast esplicito r in una stringa. Live Example

+3

Allora perché non sceglie la conversione 'string'? – interjay

+0

@interjay Stavo solo esaminando questo. Non ho visto quell'operatore quando ho scritto la risposta, – NathanOliver

+6

Bella presa. Se volessimo spiegare perché l'implementazione di 'operator double()' su tipi che non rappresentano un numero è una cattiva pratica, sarebbe difficile trovare un'illustrazione migliore :-) – dasblinkenlight

6

Dal momento che non ha fornito una operator<< sovraccarico per Rectangle, il compilatore considera altri sovraccarichi per i quali gli argomenti possono essere convertiti ai tipi di parametri.

Se uno dei sovraccarichi sono modelli, la sostituzione dell'argomento modello avviene prima della risoluzione del sovraccarico. Il compilatore tenta di dedurre i parametri del modello dai tipi di argomenti forniti alla funzione.

Il string sovraccarico non è considerato a causa di un guasto template sostituzione argomento:

template <class CharT, class Traits, class Allocator> 
std::basic_ostream<CharT, Traits>& 
    operator<<(std::basic_ostream<CharT, Traits>& os, 
       const std::basic_string<CharT, Traits, Allocator>& str); 

Template argomento sostituzione non considera conversioni definite dall'utente, in modo che il compilatore non può dedurre i tipi CharT, Traits oppure Allocator dal tipo Rectangle, quindi questo sovraccarico non partecipa alla risoluzione di sovraccarico. (Ricordiamo che std::string è solo un typedef di std::basic_string<char, std::char_traits<char>, std::allocator<char>>.)

Pertanto v'è un sovraccarico di operator<< che è una corrispondenza meglio di qualsiasi altro, e cioè il double sovraccarico. Non un modello, ma una funzione membro di un modello di classe.

basic_ostream<CharT, Traits>& basic_ostream<CharT, Traits>::operator<<(double); 
+0

Si noti che l'ultimo modello è banale; 'std :: cout' eredita da' std :: basic_ostream > '. Non è necessario sostituire gli argomenti del modello. – MSalters

Problemi correlati