5

Ich versuche den uniformen Intializer mit der String-Klasse von C++. Unten ist der Code:C++ - Uniform Initialisierer mit Std :: string

#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 
    string str1 {"aaaaa"}; 
    string str2 {5, 'a'}; 
    string str3 (5, 'a'); 

    cout << "str1: " << str1 << endl; 
    cout << "str2: " << str2 << endl; 
    cout << "str3: " << str3 << endl; 

    return 0; 
} 

Der Ausgang wäre:

str1: aaaaa 
str2: a 
str3: aaaaa 

Das machte ich meinen Kopf gekratzt. Warum str2 kann nicht das gewünschte Ergebnis als str3 erreicht?

+2

"Uniform" Initialisierung ... –

Antwort

2

std::string a hat Konstruktor, der ein initializer_list Argument übernimmt.

basic_string(std::initializer_list<CharT> init, 
       const Allocator& alloc = Allocator()); 

Das Konstruktor immer Vorrang erhält, wenn Sie verwenden, um eine verspannt-init-Listestd::string zu konstruieren. Die anderen Konstruktoren werden nur berücksichtigt, wenn die Elemente braced-init-list nicht in den Typ der Elemente in initializer_list konvertiert werden können. Dies wird in [over.match.list]/1 erwähnt.

Anfänglich sind die Kandidaten Funktionen die Initialisierer-Liste Bauer ([dcl.init.list]) der Klasse T und die Argumentliste besteht aus der Initialisiererliste als ein einziges Argument.

In Ihrem Beispiel das erste Argument 5 ist implizit konvertierbar char, so dass der initializer_list Konstruktor lebensfähig ist, und es gewählt wird.

Dies ist offensichtlich, wenn Sie

void print(char const *prefix, string& s) 
{ 
    cout << prefix << s << ", size " << s.size() << ": "; 
    for(int c : s) cout << c << ' '; 
    cout << '\n'; 
} 

string str1 {"aaaaa"}; 
string str2 {5, 'a'}; 
string str3 (5, 'a'); 

print("str1: ", str1); 
print("str2: ", str2); 
print("str3: ", str3); 

Ausgang jedes Zeichen in den Streichern als int s drucken:

str1: aaaaa, size 5: 97 97 97 97 97 
str2: a, size 2: 5 97 
str3: aaaaa, size 5: 97 97 97 97 97 

Live demo

+0

Danke. Irgendwie habe ich die Idee, was hier vor sich geht. Ich bevorzuge immer die einheitliche Initialisierung, da mir von nun an gesagt wurde, dass es die beste Vorgehensweise ist (ich bin noch neu in C++). Sieht so aus, als müsste ich von nun an vorsichtig sein. – Hilman

+1

@Hilman Wie du herausgefunden hast, funktioniert es nicht immer * so einheitlich *. Mit 'vector ' zum Beispiel, 'vector v1 {4,2}, v2 (4,2);'.Hier enthält 'v1' 2 ganze Zahlen, 4 und 2, während 'v2' 4 ganze Zahlen enthält, die jeweils auf 2 initialisiert sind. – Praetorian

8

Sie verwenden std::string's constructor mit diesem siganture

std::basic_string(std::initializer_list<CharT> init, const Allocator& alloc = Allocator()); 

und dem Compiler 5 als char Typen behandelt, was zu einem ASCII Typ übersetzt, das nicht auf dem Bildschirm gedruckt wird. Wenn Sie, dass 5 zu einem druckbaren Wert zu ändern, sagen A deren ASCII-Wert ist 65,

string str2 {65, 'a'}; 

es gedruckt wird:

Aa 

es Siehe Live on Coliru mit einer zusätzlichen Darstellung