Dạng sai:
int &z = 12;
Hình thức đúng:
int y;
int &r = y;
Câu hỏi :
Tại sao mã đầu tiên bị sai? " Ý nghĩa " của lỗi trong tiêu đề là gì?
Dạng sai:
int &z = 12;
Hình thức đúng:
int y;
int &r = y;
Câu hỏi :
Tại sao mã đầu tiên bị sai? " Ý nghĩa " của lỗi trong tiêu đề là gì?
(ostringstream() << "x=" << x).str()
Câu trả lời:
C ++ 03 3.10 / 1 nói: "Mọi biểu thức đều là một giá trị hoặc một giá trị." Điều quan trọng cần nhớ là lvalueness so với rvalueness là thuộc tính của biểu thức, không phải của đối tượng.
Giá trị đặt tên các đối tượng tồn tại ngoài một biểu thức. Ví dụ, obj
, *ptr
, ptr[index]
, và ++x
tất cả đều lvalues.
Giá trị là giá trị tạm thời biến mất ở cuối biểu thức đầy đủ mà chúng tồn tại ("ở dấu chấm phẩy"). Ví dụ, 1729
, x + y
, std::string("meow")
, và x++
tất cả đều rvalues.
Toán tử address-of yêu cầu rằng "toán hạng của nó phải là một giá trị". nếu chúng ta có thể lấy địa chỉ của một biểu thức, biểu thức là một giá trị, nếu không nó là một giá trị.
&obj; // valid
&12; //invalid
int & = 12;
không hợp lệ, tiêu chuẩn nói rằng một chuỗi ký tự là giá trị, các ký tự khác là giá trị.
std::string("meow")
xây dựng một đối tượng kiểu std::string
và mang lại một rvalue mà chỉ định đối tượng này, 1729
không có tác dụng phụ và sản lượng giá trị 1729 như là một loại giá trị int
.
"Lvalues name objects that persist beyond a single expression."
đúng 100%. Ngược lại, ví dụ của bạn (const int &)1
là không chính xác, bởi vì Nó KHÔNG phải là một đối tượng "được đặt tên".
int &z = 12;
Ở phía bên phải, một đối tượng tạm thời của kiểu int
được tạo từ ký tự tích phân 12
, nhưng tạm thời không thể bị ràng buộc với tham chiếu không phải const. Do đó lỗi. Nó giống như:
int &z = int(12); //still same error
Tại sao một tạm thời được tạo ra? Bởi vì một tham chiếu phải tham chiếu đến một đối tượng trong bộ nhớ, và để một đối tượng tồn tại, nó phải được tạo trước. Vì đối tượng không được đặt tên nên nó là đối tượng tạm thời . Nó không có tên. Từ lời giải thích này, nó đã trở nên khá rõ ràng tại sao trường hợp thứ hai lại tốt.
Một đối tượng tạm thời có thể được liên kết với tham chiếu const, có nghĩa là, bạn có thể làm điều này:
const int &z = 12; //ok
Vì lợi ích của sự đầy đủ, tôi muốn nói thêm rằng C ++ 11 đã giới thiệu tham chiếu rvalue, có thể liên kết với đối tượng tạm thời. Vì vậy, trong C ++ 11, bạn có thể viết như sau:
int && z = 12; //C+11 only
Lưu ý rằng có &&
intead of &
. Cũng lưu ý rằng const
không cần thiết nữa, mặc dù đối tượng z
liên kết với là một đối tượng tạm thời được tạo ra từ tích phân-chữ 12
.
Kể từ khi C ++ 11 đã giới thiệu tham chiếu rvalue , int&
bây giờ được gọi là tham chiếu lvalue .
12
là một hằng số thời gian biên dịch không thể thay đổi không giống như dữ liệu được tham chiếu bởi int&
. Những gì bạn có thể làm là
const int& z = 12;
void f( vector<int> const & )
, nó là thành ngữ để truyền một vectơ không được sửa đổi. Vấn đề bây giờ là điều đó f( vector<int>(5) )
sẽ không chính xác và người dùng sẽ phải cung cấp một quá tải khác void f( vector<int> v ) { f(v); }
, điều này là không đáng kể.
f( vector<int>(5) )
, trình biên dịch tạo một tham chiếu tạm thời và sau đó liên kết tham chiếu với tạm thời đó, và tương tự nếu có một chuyển đổi ngầm từ 5
trực tiếp. Điều này cho phép trình biên dịch tạo ra một chữ ký duy nhất cho hàm và cho phép một người dùng triển khai hàm duy nhất. Từ đó trở đi, hành vi tương tự được xác định cho phần còn lại của việc sử dụng các tham chiếu không đổi để có tính nhất quán.
T const & r = *ptr;
, bất kỳ cách sử dụng nào sau này r
trong hàm đều có thể được thay thế *ptr
và r
không cần tồn tại trong thời gian chạy) hoặc nó có thể phải được triển khai bằng cách giữ địa chỉ của đối tượng mà nó là bí danh (coi việc lưu trữ một tham chiếu như một thành viên của một đối tượng) - mà nó được triển khai dưới dạng một con trỏ được tham chiếu tự động.
Đây là các quy tắc của ngôn ngữ C ++:
12
) là một "rvalue"int &ri = 12;
là saiBạn phải hiểu rằng đây là các quy tắc C ++. Họ chỉ là.
Thật dễ dàng để phát minh ra một ngôn ngữ khác, chẳng hạn như C ++ ', với các quy tắc hơi khác. Trong C ++ ', nó sẽ được phép tạo một tham chiếu không phải const với một giá trị rvalue. Không có gì mâu thuẫn hoặc không thể ở đây.
Nhưng nó sẽ cho phép một số mã rủi ro mà lập trình viên có thể không đạt được những gì anh ta dự định, và các nhà thiết kế C ++ đã quyết định đúng để tránh rủi ro đó.
Tham chiếu là "con trỏ ẩn" (không phải null) đến những thứ có thể thay đổi (giá trị). Bạn không thể định nghĩa chúng thành một hằng số. Nó phải là một thứ "biến".
BIÊN TẬP::
Tôi đang nghĩ về
int &x = y;
gần như tương đương với
int* __px = &y;
#define x (*__px)
đâu __px
là tên mới và #define x
chỉ hoạt động bên trong khối chứa khai báo x
tham chiếu.
const
:)
const