5

Tôi đang thử trình intializer thống nhất với lớp chuỗi của C++. Dưới đây là các mã:C++ - Trình khởi tạo đồng bộ với 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; 
} 

Kết quả sẽ là:

str1: aaaaa 
str2: a 
str3: aaaaa 

này khiến tôi gãi đầu. Tại sao str2 không thể đạt được kết quả mong muốn là str3?

+2

"Uniform" khởi ... –

Trả lời

2

std::string có hàm tạo có đối số initializer_list.

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

Đó constructor luôn được ưu tiên khi bạn sử dụng một chuẩn bị tinh thần-init-list để xây dựng std::string. Các nhà xây dựng khác chỉ được xem xét nếu các phần tử trong braced-init-list không thể chuyển đổi thành loại phần tử trong các initializer_list. Điều này được đề cập trong [over.match.list]/1.

Ban đầu, các chức năng ứng cử viên là các nhà thầu initializer-list ([dcl.init.list]) của lớp T và danh sách đối số bao gồm các danh sách initializer như một đối số duy nhất.

Trong ví dụ của bạn, đối số đầu tiên 5 là mặc nhiên chuyển đổi thành char, vì vậy các nhà xây dựng initializer_list là khả thi, và nó được chọn.

Đây là điều hiển nhiên nếu bạn in mỗi nhân vật trong chuỗi như int s

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

Output:

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ảm ơn. Loại có ý tưởng những gì đang xảy ra ở đây. Tôi luôn luôn thích khởi tạo thống nhất kể từ khi tôi đã nói nó là thực hành tốt nhất từ ​​bây giờ (tôi vẫn còn mới đến C + +). Có vẻ như tôi phải cẩn thận từ bây giờ. – Hilman

+1

@Hilman Như bạn đã phát hiện ra, nó không phải lúc nào cũng hoạt động như vậy * đồng nhất *. Ví dụ, với 'vector ', vector v1 {4,2}, v2 (4,2); '.Ở đây 'v1' chứa 2 số nguyên, 4 và 2, trong khi' v2' chứa 4 số nguyên, mỗi số nguyên được khởi tạo thành 2. – Praetorian

8

Bạn đang sử dụng std::string's constructor với siganture này

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

Và trình biên dịch xử lý 5 như một loại char, mà dịch để một kiểu ASCII mà không được in trên màn hình. Nếu bạn thay đổi điều đó 5 đến một giá trị có thể in được, nói A có giá trị ASCII là 65,

string str2 {65, 'a'}; 

nó sẽ in:

Aa 

Xem nó Live on Coliru với một minh hoạ thêm

Các vấn đề liên quan