Nicolai Josuttis Präsentation "Der Albtraum der Initialisierung in C++" auf der CppCon 2018 enthielt an einer Stelle den folgenden Code:
std::vector< std::string > v07 = {{ "1", "2" }};
Nicolai sagte folgendes (Transkriptionsmine):
Das Problem ist, was hier passiert, wir interpretieren diese beiden Parameter als Iteratoren . Das sind also Iteratoren, also ist dies der Anfang des Bereichs und dies ist das Ende des Bereichs, und sie sollten sich auf denselben Bereich von Zeichen beziehen. Da Zeichen implizit in Zeichenfolgen konvertiert werden, wird diese kompiliert. Wenn du Glück hast, bekommst du einen Coredump. Wenn nicht, hast du ein großes Problem.
Er hat mich dort verloren. Kann jemand genau erklären, was hier Schritt für Schritt vor sich geht?
Unten Code
std::vector< std::string > v07 = { { "1", "2" } };
ist äquivalent zu
std::string s = {"1","2"}; // call string(const char*, const char*)
std::vector<std::string> v07 = {s}; // initializer list with one item
das Problem ist mit
s={"1","2"};
Dies ruft den Konstruktor string(const char* start, const char* end)
auf, aber start
und end
müssen auf dasselbe Zeichenfolgenobjekt verweisen. "1" und "2" sind zwei verschiedene Objekte, daher führt dies zu UB.