Hängen Sie int an std::string an

Lesezeit: 5 Minuten

Benutzer-Avatar
Marineliebhaber

Ich habe zwei verschiedene Möglichkeiten ausprobiert, um an anzuhängen int zu einem std::stringund zu meiner Überraschung bekam ich unterschiedliche Ergebnisse:

#include <string>

int main()
{
    std::string s;
    s += 2;     // compiles correctly
    s = s + 2;  // compiler error

    return 0;
}

Warum kompiliert und funktioniert es richtig, wenn ich die += Operator, aber scheitern, wenn ich die verwende + Operator?

Ich glaube nicht, dass die Frage wie How to concatenate a std::string and an int lautet?

Bei dieser Frage verwendet keine Antwort += Betreiber.Und der Unterschied zwischen +=
und + Betreiber von std::string ist der Schlüssel, um meine Zweifel zu lösen.

Ehrlich gesagt ist die Frage ein gutes Beispiel dafür, warum C++ so schwer zu beherrschen ist.

  • Sie fügen keine Zeichenfolgendarstellung der Ganzzahl hinzu 2 in beiden Fällen. Sie verwenden möchten std::to_string.

    – Jesper Juhl

    4. August 2017 um 11:23 Uhr

  • Ich bin mir nicht sicher, aber ich denke, die operator+ erwartet a string nicht ein int

    – Bo Halim

    4. August 2017 um 11:25 Uhr

  • Sie können keine anhängen int zu einer Schnur. Was Sie tun können, ist die anhängen Text die einen ganzzahligen Wert für eine Zeichenfolge darstellt. Verlieren Sie diesen Conversion-Schritt nicht aus den Augen.

    – Peter Becker

    4. August 2017 um 11:32 Uhr


  • Mögliches Duplikat von How to concatenate a std::string and an int?

    – Cole Tobin

    6. August 2017 um 6:34 Uhr

Benutzer-Avatar
iBug

TL;DR operator+= ist eine Klassenmitgliedsfunktion in class stringwährend operator+ ist eine Template-Funktion.

Die Standardklasse template<typename CharT> basic_string<CharT> hat eine überladene Funktion basic_string& operator+=(CharT)und Zeichenfolge ist nur basic_string<char>.

Da Werte, die in einen niedrigeren Typ passen, im Ausdruck automatisch in diesen Typ umgewandelt werden können s += 2die 2 ist nicht behandelt wie intaber char stattdessen. Es hat exakt gleiche Wirkung wie s += '\x02'. Ein Zeichen mit ASCII-Code 2 (STX) wird angehängt, nicht das Zeichen ‘2’ (mit ASCII-Wert 50 oder 0x32).

String hat jedoch keine überladene Member-Funktion wie string operator+(int), s + 2 ist kein gültiger Ausdruck und löst daher während der Kompilierung einen Fehler aus. (Mehr unten)

Sie können die Operator+-Funktion in Zeichenfolgen auf folgende Weise verwenden:

s = s + char(2); // or (char)2
s = s + std::string(2);
s = s + std::to_string(2); // C++11 and above only

Für Leute, die sich Sorgen darüber machen, warum 2 nicht automatisch gecastet wird char mit operator+,

template <typename CharT>
  basic_string<CharT>
  operator+(const basic_string<CharT>& lhs, CharT rhs);

Oben ist der Prototyp[note] für den Plusoperator in s + 2und da es sich um eine Vorlagenfunktion handelt, ist eine Implementierung von beiden erforderlich operator+<char> und operator+<int>, was widersprüchlich ist. Einzelheiten finden Sie unter Warum wird das automatische Downcasting nicht auf Vorlagenfunktionen angewendet?

Inzwischen ist der Prototyp von operator+= ist:

template <typename CharT>
class basic_string{
    basic_string&
      operator+=(CharT _c);
};

Sie sehen, hier gibt es keine Vorlage (es ist eine Klassenmitgliedsfunktion), also leitet der Compiler ab, dass der Typ CharT ist char von der Klassenimplementierung und int(2) wird automatisch eingegossen char(2).


Notiz: Unnötiger Code wird beim Kopieren aus der C++-Standard-Include-Quelle entfernt. Dazu gehören Typname 2 und 3 (Traits und Allocator) für die Template-Klasse „basic_string“ und unnötige Unterstriche, um die Lesbarkeit zu verbessern.

  • Und warum die 2 im Ausdruck s + 2 wird nicht als behandelt char aber in s += 2?

    – André Kampling

    4. August 2017 um 11:38 Uhr


  • @AndreKampling: Es hat damit zu tun, dass += eine Nicht-Vorlagenfunktion ist, aber + eine Vorlagenfunktion ist.

    – Bathseba

    4. August 2017 um 11:45 Uhr

Benutzer-Avatar
Bathseba

s += 2; tut nicht das, was Sie denken, dass es tut. Es ruft die Überladenen += Betreiber zu a char. Es tut nicht anhängen Charakter '2'sondern das Zeichen mit Wert 2, und das Ergebnis hängt von der ab Codierung auf Ihrer Plattform verwendet.

Es ist keine zuzulassende Operatorüberladung definiert s + 2 kompilieren1. Daher der Fehler.

Die Lösung in beiden Fällen ist zu verwenden std::to_string(2) eher als das int wörtlich 2.


1 Der Grund ist im Wesentlichen, weil operator+= ist keine Template-Funktion, aber std::operator+ ist, und die Überladungsauflösung bevorzugt eine Nicht-Vorlagenfunktion gegenüber einer Vorlagenfunktion.

  • Aber ich habe nicht gesehen, warum der Compiler aufruft string& operator+= (char c); aber nicht string operator+ (const string& lhs, char rhs);?

    – André Kampling

    4. August 2017 um 11:32 Uhr

  • Ich denke, das ist eine (gute) Frage für sich (es hat damit zu tun, dass der Compiler versuchen muss, 2 in a umzuwandeln std::string, was es nicht kann). Warum nicht fragen?

    – Bathseba

    4. August 2017 um 11:32 Uhr


  • @AndreKampling: Ich habe kapituliert und mehr Details hinzugefügt.

    – Bathseba

    4. August 2017 um 11:44 Uhr

  • Die Tatsache, dass s += 2 kompiliert fühlt sich wirklich wie ein Defekt an

    – Tristan Brindle

    4. August 2017 um 12:02 Uhr

  • Siehe auch diese Frage, die sich auf diese Frage bezieht: Warum wird kein automatisches Downcasting auf Vorlagenfunktionen angewendet?.

    – André Kampling

    4. August 2017 um 12:35 Uhr


Der richtige Weg, um Ihre hinzuzufügen string wäre

std::string s;
s += std::to_string(2);
s = s + std::to_string(2);

  • Beachten Sie, dass std::to_string ist nur auf C++11 und höher verfügbar.

    – André Kampling

    4. August 2017 um 11:23 Uhr

  • @AndreKampling Es ist 2017. Sofern eine Frage nicht speziell gekennzeichnet ist oder C++03 anderweitig erwähnt, ist es fair anzunehmen, dass C++11-Unterstützung verfügbar ist.

    – Aschepler

    5. August 2017 um 11:31 Uhr


  • Die allgemein empfohlene Methode, ein Objekt in einen String auszugeben, besteht darin, einen std::ostringstream zu verwenden, das Objekt dorthin zu streamen und dann die .str()-Funktion zu verwenden, um den std::string aus dem std::ostringstream abzurufen. Dies sollte für alle C++-Dialekte und alle Objekte funktionieren, die einen Einfügeoperator haben.

    – CSM

    5. August 2017 um 19:21 Uhr


  • @CSM “allgemein empfohlen”? Und warum sollte das sein? Die Funktion std::to_string ist in diesem Zusammenhang durchaus sinnvoll und wurde genau zu diesem Zweck geschaffen.

    – Cory Kramer

    5. August 2017 um 19:50 Uhr

Benutzer-Avatar
Xatyrisch

Während die @CoryKramer-Antwort Ihnen die richtige Möglichkeit zum Hinzufügen einer Ganzzahl zu einer Zeichenfolge gibt, wird nicht erklärt, warum die Anweisung s = s + 2 kompiliert nicht.

Der Unterschied zwischen den beiden Anweisungen besteht darin, dass Sie in der ersten die verwenden std::string ‘s += Operator während in der zweiten Anweisung der Compiler versucht, umzuwandeln 2 zu einer Schnur.

Es gibt keine implizite Konvertierung zwischen int und std::string. Sie können jedoch ein wirken int zu chardeswegen also s += 2funktioniert.

1019500cookie-checkHängen Sie int an std::string an

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy