2010-08-28 29 views
14

Tại sao người ta có thể làmString nối

const string exclam = "!"; 
const string str = exclam + "Hello" + " world"; 

Và không thể làm điều này:

const string exclam = "!"; 
const string str = "Hello" + " world" + exclam; 

Tôi biết (mặc dù không thể hiểu tại sao) mà nó không được phép làm:

const string str = "Hello" + " world" + "!"; 

vì nó sẽ được hiểu là const char[6] + const char[6] + const char[1], vì vậy từ phía bên kia, tại sao điều này cũng không được phép hoặc tại sao lại sử dụng s char[] và không phải string.

+4

Nếu bạn muốn nối chuỗi ký tự chuỗi, sau đó không sử dụng '+': 'const chuỗi str =" Hello "" world "+ exclam;' – UncleBens

Trả lời

18

Toán tử + là liên kết trái (được đánh giá từ trái sang phải), do đó, bên trái nhất + được đánh giá trước tiên.

exclam là một đối tượng std::string rằng quá tải operator+ để cả hai điều sau đây thực hiện nối:

exclam + "Hello" 
"Hello" + exclam 

Cả hai trả về một đối tượng std::string chứa chuỗi nối vào nhau.

Tuy nhiên, nếu hai điều đầu tiên là "thêm" là chuỗi literals, như trong:

"Hello" + "World" 

không có đối tượng kiểu lớp liên quan (không có std::string đây). Các chuỗi ký tự được chuyển đổi thành con trỏ và không có mã được xây dựng trong operator+ cho con trỏ.

+1

@sbi: Các nhà khai thác không bao giờ được đánh giá, toán hạng làm. –

+0

@Prasoon: Một nitpick hợp lệ mà tôi không thể làm bất kỳ điều gì vì tôi không thể chỉnh sửa nhận xét đó nữa. (Tuy nhiên, bạn không trả lời câu hỏi ngụ ý của tôi.) – sbi

+0

@sbi: Các toán tử này được gọi là "liên kết trái" trong tiếng Anh. Khi tôi đăng lần đầu, tôi không thể nhớ liệu "X liên kết" có nghĩa là toán tử "X-nhất" được đánh giá đầu tiên hay cuối cùng (trong đó "X" là "trái" hoặc "phải"). Cảm ơn. @Prasoon: Về mặt kỹ thuật, _expressions_ được đánh giá :-) –

3

Đó là vì bạn đang lén lút const char[6] + const char[6], điều này không được phép, như bạn đã nói.

Trong C++, chuỗi ký tự (nội dung giữa dấu ngoặc kép) được hiểu là const char[] s.

Bạn có thể ghép một string với const char[] (và ngược lại) vì toán tử + bị ghi đè trong chuỗi, nhưng không thể ghi đè lên loại cơ bản.

+1

@Philip: Chuỗi ký tự có loại ' const char [N] 'trong đó' N' là kích thước của chuỗi ký tự. Nó là một mảng, và giống như một mảng, nó có thể được chuyển đổi hoàn toàn thành một con trỏ tới phần tử đầu tiên của nó (một 'const char *'). Trong C++, trong khi việc chuyển đổi một chuỗi ký tự thành (không phải '' '' 'char *' không được chấp nhận, nó vẫn được cho phép. –

3
const string exclam = "!"; // Initialize a c++ string with an ansi c string 
const string str = exclam + "Hello" + " world"; // Using the operator+ method of exclam 

Bạn có thể làm điều đó bởi vì operator+ của exclam sẽ trả về một chuỗi mới có chứa "Hello", mà trên đó bạn sau đó gọi operator+ với "thế giới" như tham số, vì vậy bạn sẽ có được một chuỗi khác mà, cuối cùng, được gán cho str bằng phương tiện của hàm tạo bản sao.

Mặt khác

const string str = "Hello" + " world" + exclam; 

không thể được thực hiện vì "Hello" chỉ là một const char *, mà không có một operator+ tham gia một const char * như tham số.

0

(câu trả lời mới, điều này là không thể trở lại trong năm 2010)

Bây giờ bạn có thể viết

const string str = "Hello"s + " world"s + "!"s; 
//      ^  ^ ^

Bằng cách thêm rằng s sau một chuỗi chữ, bạn nói với trình biên dịch nó thực sự là một std::string và không a const char[]. Điều đó có nghĩa là bạn có thể gọi các thành viên hoạt động trên đó. Ví dụ. ("ABC"s).back() nhưng cũng +

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