2009-07-24 8 views
19

Ich bin heute in einem Programm auf eine interessante Situation gestoßen, wo ich versehentlich eine vorzeichenlose ganze Zahl einer std :: string zugewiesen hat. Der VisualStudio C++ - Compiler gab keine Warnungen oder Fehler darüber aus, aber ich bemerkte den Fehler, als ich das Projekt ausführte, und es gab mir überflüssige Zeichen für meine Zeichenfolge.Warum lässt C++ zu, dass eine Ganzzahl einer Zeichenfolge zugewiesen wird?

Dies ist eine Art, was der Code aussah:

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string = my_number; 

auch folgende Code kompiliert fein:

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string.operator=(my_number); 

Die folgenden Ergebnisse zu einem Fehler:

unsigned int my_number = 1234; 
std::string my_string(my_number); 

Was es geht voran? Wie kommt es, dass der Compiler den Build mit dem letzten Codeblock stoppt, aber die ersten 2 Codebausteine ​​erstellen?

+0

Was sind die Compilerfehler? Für mich kompiliert und funktioniert g ++ v4.4 korrekt – CsTamas

+0

Es tut mir leid, ich habe einen Fehler mit dem 2. Codeblock gemacht - es kompiliert. Die letzte schlägt mit einem Fehler fehl, da es keinen std :: string -Konstruktor gibt, der einen unsigned int akzeptiert. – user55417

Antwort

28

Da Zeichenfolge ist von char zuweisbar, und int ist implizit in char konvertierbar.

+0

Wie kommt es, dass Int für die letzten 2 Blöcke nicht implizit gecastet wird? Was meinst du, dass ich Operator = nicht explizit aufrufen kann? Weil das Folgende funktioniert: my_string.operator = ("Hallo Welt"); – user55417

+0

Ist 'my_string.operator = (my_number)' nicht ein expliziter Aufruf von 'operator ='? Was verstehe ich hier falsch? – sbi

+0

"Wie kommt es, dass der Int nicht implizit für die letzten 2 Blöcke gecastet wird?" Denn während 1234 in 16 Bits passt und da ein char sein kann, passt nicht jeder vorzeichenlose int in 16 Bits. Sobald Sie einen Typ mit einem größeren Bereich als einem Zeichen angegeben haben, haben Sie den Compiler daran gehindert, den Wert implizit in ein Zeichen umzuwandeln. –

20

Die std :: string Klasse hat den folgenden Zuweisungsoperator definiert:

string& operator=(char ch); 

Dieser Operator durch implizite Umwandlung von unsigned int zu char aufgerufen wird.

In Ihrem dritten Fall Sie einen expliziten Konstruktor verwenden einen std::string, keine der verfügbaren Konstrukteure zu instanziiert kann eine unsigned int, oder verwenden Sie implizite Konvertierung von unsigned int akzeptieren:

string(); 
string(const string& s); 
string(size_type length, const char& ch); 
string(const char* str); 
string(const char* str, size_type length); 
string(const string& str, size_type index, size_type length); 
string(input_iterator start, input_iterator end); 
+3

"Operatoren können nicht mit funktionalen Aufruf Syntax aufgerufen werden". 13.5 (4) im C++ - Standard sagt, sie können. –

+0

"Operatoren können nicht mit funktionaler Aufrufsyntax aufgerufen werden" Das ist einfach falsch. – sbi

+1

Schade, weil die angenommene Antwort zunächst den gleichen Fehler gemacht hat, aber trotzdem abgewählt und dann korrigiert wurde, während diese Antwort ansonsten viel besser ist und abgelehnt wurde. Ich werde dafür stimmen, wenn es behoben ist. –

2

Es ist definitiv operator = (Char Ch) Call - mein Debugger trat in das ein. Und mein MS VS 2005 kompiliert das Folgen ohne Fehler.

std::string my_string(""); 
unsigned int my_number = 1234; 
my_string = my_number; 
my_string.operator=(my_number); 
0

kann ich die ersten und die dritten Situationen erklären:

my_string = 1234; 

Das funktioniert, weil String außer Kraft gesetzt Operator = (char). Sie ordnen dem String tatsächlich ein Zeichen (mit Datenüberlauf) zu. Ich weiß nicht, warum der zweite Fall zu einem Kompilierungsfehler führt. Ich habe den Code mit GCC ausprobiert und es kompiliert.

std::string my_string(1234); 

wird nicht funktionieren, weil es kein Zeichenfolgenkonstruktor ist, die ein char oder int-Argument.