2015-02-23 17 views

Trả lời

3

Cả chuỗi chữ cũng không s là con trỏ (họ là mảng), do đó phần có liên quan của tiêu chuẩn là [conv.array]:

Một vế trái hoặc rvalue kiểu "mảng của NT" hoặc "mảng liên kết không xác định của T" có thể được chuyển đổi thành giá trị bằng loại "con trỏ đến T". Kết quả là một con trỏ đến phần tử đầu tiên của mảng.

Lưu ý rằng

char const *p = s; 
f(p); 

in "giá trị trái", để chứng minh rằng công trình này như bạn mong đợi cho con trỏ.

Phụ Lục lại: bình luận: Trong trường hợp của

char *p = s; 
f(p); 

mà in "rvalue" nếu tình trạng quá tải rvalue tồn tại nhưng không gây ra một lỗi biên dịch nếu nó được lấy ra, hai phần khác của tiêu chuẩn đi vào chơi - một trong số đó dường như cấm ràng buộc của char* đến char const *const & hoàn toàn và cửa sổ kia mở lại một cửa sổ.

Đầu tiên là [dcl.init.ref]/4, trong đó

loại Với "CV1T1" và "CV2T2", "CV1T1" là tài liệu tham khảo liên quan đến để "CV2T2" nếu T1 là loại giống như T2, hoặc T1 là lớp cơ sở của T2. "CV1T1" là tham khảo tương thích với "CV2T2" nếu T1tài liệu tham khảo liên quan đến-T2CV1 là như nhau cv tuyển như, hoặc cv tuyển lớn hơn, CV2. (...)

Nó tiếp tục theo chiều dài về các quy tắc chính xác để khởi tạo tham chiếu, tất cả đều phù hợp nhưng không may là quá dài đối với câu trả lời SO.Câu chuyện dài được viết ngắn gọn là tham chiếu đến cv1T1 có thể được khởi tạo với đối tượng cv2T2 nếu hai tham chiếu tương thích với tham chiếu.

gì mặt luật pháp, điều này có nghĩa đối với trường hợp của chúng tôi là char*char const * không tham khảo tương thích (mặc dù char*char *const sẽ được), vì char* không phải là char const * cũng không phải là một một lớp cơ sở của người kia. Hạn chế này có ý nghĩa nếu bạn xem xét các mảnh trái phép mã sau đó sẽ là hợp pháp khác:

const char c = 'c'; 
char *pc; 
const char*& pcc = pc; // #1: not allowed 
pcc = &c; 
*pc = 'C';    // #2: modifies a const object 

này được chuyển thể từ một ví dụ tương tự trong [conv.qual]/4 có sử dụng một con trỏ đến con trỏ để chứng minh cùng một vấn đề.

[conv.qual] cũng là phần có liên quan khác mà mở cửa sổ trở lại trong Nó nói trong [conv.qual]/1:.

Một prvalue kiểu "con trỏ đến CV1T "có thể được chuyển đổi sang một prvalue kiểu "con trỏ đến CV2T" nếu" CV2T "là hơn cv-có trình độ hơn" CV1T "

Nó sau từ tất cả điều này mà char* có thể được chuyển đổi sang char const * (đó là tài liệu tham khảo tương thích với char const *const), đó là lý do tại sao mã vẫn biên dịch nếu quá tải rvalue của f được lấy ra. Tuy nhiên, kết quả của chuyển đổi này là giá trị gia tăng, vì vậy nếu nó có mặt, quá tải rvalue được ưu tiên trong độ phân giải quá tải.

char* glvalue ->char* prvalue (bởi [conv.lval]) ->char const * prvalue)

+0

nên không 'char * p = s; f (p); 'cũng là" lvalue "? Tại sao nó "rvalue"? – alice

+0

Bởi vì một 'char *' không thể bị ràng buộc bởi tham chiếu đến 'char const *' (nó sẽ cho phép bạn phá vỡ const đúng đắn). [conv.qual] áp dụng, lần đầu tiên yêu cầu chuyển đổi từ rvalue sang rvalue và kết quả là các giá trị gia tăng. – Wintermute

+0

Tôi không chắc chắn chính xác const bạn đang đề cập đến. 'Type &' chỉ liên kết với các giá trị có thể sửa đổi, nhưng 'const Type &' liên kết với mọi thứ. Ví dụ, 'string s1 (" abc "); const string & s2 = s1; 'biên dịch tốt. – alice

1

s là một mảng giá trị (như vậy là "abc", cho rằng chuỗi ký tự chuỗi là lvalues). Để có được một con trỏ, việc chuyển đổi mảng-thành-con trỏ được thực hiện. Chuyển đổi này tạo ra một giá trị con trỏ, ưu tiên liên kết với quá tải tham chiếu rvalue.

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