In der C ++ - Standardbibliothek gibt es Funktionen zum Konvertieren von Zeichenfolgen in numerische Typen:
stoi
stol
stoll
stoul
stoull
stof
stod
stold
aber ich finde es mühsam, sie im Vorlagencode zu verwenden. Warum gibt es keine Vorlagenfunktionen wie:
template<typename T>
T sto(...)
Zeichenfolgen in numerische Typen konvertieren?
Ich sehe keinen technischen Grund, sie nicht zu haben, aber vielleicht fehlt mir etwas. Sie können darauf spezialisiert sein, die zugrunde liegenden benannten Funktionen aufzurufen und nicht numerische Typen zu verwenden enable_if
/ concepts
zu deaktivieren.
Gibt es in der Standardbibliothek vorlagenfreundliche Alternativen, um Zeichenfolgen effizient in numerische Typen umzuwandeln und umgekehrt?
c++
string-conversion
Mircea Ispas
quelle
quelle
Antworten:
C ++ 17 hat eine solche generische String-to-Number-Funktion, die jedoch anders benannt ist. Sie gingen mit
std::from_chars
, was für alle numerischen Typen überladen ist.Wie Sie sehen können, nimmt die erste Überladung einen beliebigen Ganzzahltyp als Ausgabeparameter und weist ihm nach Möglichkeit den Wert zu.
Es kann folgendermaßen verwendet werden:
Wie Sie sehen können, kann es im generischen Kontext funktionieren.
quelle
Es ist keine Vorlage und funktioniert nicht mit Gebietsschemas. Wenn dies jedoch kein Show-Stopper ist, hat C ++ 17 bereits das, was Sie wollen:
std::from_chars
Es gibt Überladungen für alle Ganzzahl- und Gleitkommatypen, und die Schnittstelle ist bis auf die letzten Parameter, die für die Ganzzahl- bzw. Gleitkommatypen unterschiedlich sind, identisch (wenn die Standardeinstellung jedoch in Ordnung ist, müssen Sie dies nicht tun etwas ändern). Da dies keine länderbezogene Funktion ist, ist sie auch recht schnell. Es schlägt jede andere Funktion zur Umwandlung von Zeichenfolgen in Werte und ist im Allgemeinen um Größenordnungen.
Es gibt ein sehr gutes CPPCON-Video über Stephan T. Lavavej
<charconv>
(in dem der Headerfrom_chars
lebt), das Sie hier über seine Verwendung und Leistung sehen können: https://www.youtube.com/watch?v=4P_kbF0EbZMquelle
stoi
und seine Freunde (die in der Frage erwähnten Conversions) funktionieren auch nicht mit Gebietsschemas, das ist also kein Showstopper.Sie würden nicht viel gewinnen, weil in einem Ausdruck wie
Es gibt keine (einfache) Möglichkeit, den gewünschten Typ für den Vorlagenparameter abzuleiten. Du müsstest schreiben
was in gewissem Maße den Zweck der Bereitstellung einer generischen Funktion zunichte macht. Auf der anderen Seite a
wäre von Nutzen, wie Sie erkannt haben. In C ++ 17 gibt es etwas
std::from_chars
, das mehr oder weniger genau das tut (es ist keine Vorlage, sondern eine Reihe von Überladungen, und es werden Zeiger auf Zeichen anstelle einer Zeichenfolge verwendet, aber das sind nur geringfügige Details).PS Es gibt keine einfache Möglichkeit, den gewünschten Typ im obigen Ausdruck abzuleiten, aber es gibt eine Möglichkeit. Ich glaube nicht, dass der Kern Ihrer Frage genau die Signatur war, nach der Sie gefragt haben, und ich denke nicht, dass das Folgende eine gute Möglichkeit ist, sie zu implementieren, aber ich wusste, dass es eine Möglichkeit gibt, die oben genannten zu
int x = sto("1");
kompilieren, und ich war neugierig, sie zu sehen in Aktion.Dies funktioniert wie beabsichtigt, hat aber schwerwiegende Nachteile, vielleicht am wichtigsten ist, dass es das Schreiben ermöglicht
auto x = sto(s);
, dh es ist leicht falsch zu verwenden.quelle
auto x = sto(s)
? Diese spezielle Implementierung bricht ab, daconverter::x
es sich um eine Referenz handelt, die außerhalb des Gültigkeitsbereichs liegt, die jedoch behoben werden kann. Entfernen Sie einfach die Referenz und verlassen Sie sich aufstd::string
die Verschiebungssemantik.converter
. Außerdem bin ich mir nicht sicher, ob die Verwendung eines Vorlagenkonvertierungsoperators die beste Wahl war, Dinge, die behoben werden könnten. Vielleicht ist es nicht so schlimm, wie ich ursprünglich dachteEine mit allen kompatible Lösung (auch ältere C ++ - Compiler wie C ++ - 98) ist die Verwendung von boost :: lexical_cast , einer Vorlage zum Konvertieren zwischen numerischen und Zeichenfolgentypen auf beide Arten.
Beispiel:
Siehe: https://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm
quelle
In älteren C ++ - Versionen ist stringstream Ihr Freund. Wenn ich das richtig verstehe, könnte das Folgende für Sie interessant sein. Es ist C ++ 11.
https://wandbox.org/permlink/nUNiUwWWTr7a0NXM
Diese Methode funktioniert in C ++ 11 und ist ziemlich allgemein. Nach meiner Erfahrung ist diese Methode robust, aber nicht die leistungsfähigste.
quelle