5

Я пытаюсь использовать унифицированный intializer со строковым классом C++. Ниже приведен код:C++ - Унифицированный инициализатор с 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; 
} 

Выход будет:

str1: aaaaa 
str2: a 
str3: aaaaa 

Это заставило меня почесал голову. Почему str2 не может достичь желаемого результата как str3?

+2

"Uniform" инициализации ... –

ответ

2

std::string имеет конструктор, который принимает аргумент initializer_list.

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

Этот конструктор всегда получает преимущество при использовании рамно-Init-лист построить std::string. Другие конструкторы рассматриваются только в том случае, если элементы в списке braced-init-list не конвертируются в тип элементов в initializer_list. Это упоминается в [over.match.list]/1.

Первоначально функции кандидаты являются инициализатор-список Конструкторы ([dcl.init.list]) класса T и список аргументов состоит из списка инициализации в качестве единственного аргумента.

В вашем примере, первый аргумент 5 неявно конвертируются в char, поэтому initializer_list конструктор жизнеспособна, и она будет выбрана.

Это видно при печати каждого символа в строках, как int сек

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); 

Выход:

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

Спасибо. Вид получил идею, что здесь происходит. Я всегда предпочитаю унифицированную инициализацию, так как мне сказали, что это лучшая практика с этого момента (я все еще новичок в C++). Похоже, теперь я должен быть осторожнее. – Hilman

+1

@Hilman Как вы узнали, он не всегда работает так * равномерно *. С 'vector ' например, 'vector v1 {4,2}, v2 (4,2);'.Здесь 'v1' содержит 2 целых числа, 4 и 2, а' v2' содержит 4 целых числа, каждый из которых инициализируется 2. – Praetorian

8

Вы используете std::string's constructor с этим siganture

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

и компилятор обработанного 5 как тип char, который переводит к ASCII типа, не напечатанным на экране. Если вы изменяете, что 5 к печати значения, скажут A которого ASCII значение 65,

string str2 {65, 'a'}; 

он будет печатать:

Aa 

Посмотри Live on Coliru с дополнительной иллюстрацией