Tôi đã được buffled bởi mã tương tự quá - tại nắm tay. Đó là "tại sao tôi gán giá trị cho một cuộc gọi hàm và tại sao trình biên dịch lại hài lòng với nó?" Tôi tự hỏi. Nhưng khi bạn nhìn vào những gì xảy ra "đằng sau", nó có ý nghĩa.
Như cpp và những người khác poined ra, lvalues là "vị trí bộ nhớ" có địa chỉ và chúng ta có thể gán giá trị cho họ. Bạn có thể tìm thêm thông tin về chủ đề của các giá trị và giá trị on the internet.
Khi chúng ta nhìn vào các chức năng:
int& fun()
{
static int x = 10;
return x;
}
Tôi di chuyển các & to go, do đó, nó rõ ràng hơn chúng ta đang trở về một tham chiếu đến int.
Chúng tôi thấy chúng tôi có x, đó là lvalue - địa chỉ này có địa chỉ và chúng tôi có thể gán cho nó. Nó cũng là tĩnh, làm cho nó đặc biệt - nếu nó không tĩnh, tuổi thọ (phạm vi) của biến sẽ kết thúc với ngăn xếp thư giãn khi rời khỏi hàm và sau đó tham chiếu có thể trỏ tới bất kỳ lỗ đen nào tồn tại trong vũ trụ. Tuy nhiên, x là tĩnh, nó sẽ tồn tại ngay cả sau khi chúng ta rời khỏi hàm (và khi chúng ta quay lại hàm) và chúng ta có thể truy cập nó bên ngoài hàm.
Chúng tôi đang trả lại tham chiếu đến một int và kể từ khi chúng tôi trả lại x, tham chiếu đến x. Sau đó, chúng tôi có thể sử dụng tham chiếu để thay đổi x bên ngoài chức năng. Vì vậy:
int main()
{
fun();
Chúng tôi chỉ gọi hàm. Biến x (trong phạm vi chức năng thú vị) được tạo, nó có giá trị là 10 được gán. Đó là địa chỉ và giá trị tồn tại ngay cả sau khi chức năng còn lại - nhưng chúng ta không thể sử dụng giá trị của nó, vì chúng ta không có địa chỉ của nó.
fun() = 30;
Chúng tôi gọi hàm và sau đó thay đổi giá trị của x. Giá trị x được thay đổi thông qua tham chiếu được hàm trả về. LƯU Ý: chức năng được gọi là đầu tiên và chỉ sau khi cuộc gọi chức năng được hoàn thành, sau đó, việc chuyển nhượng diễn ra.
int& reference_to_x = fun(); // note the &
Bây giờ chúng ta (cuối cùng) giữ tham chiếu đến x trả về bởi hàm. Bây giờ chúng tôi có thể thay đổi x mà không cần gọi hàm trước.(reference_to_x lẽ sẽ có địa chỉ giống như x có bên trong hàm vui vẻ)
int copy_of_x = fun(); // no & this time
Lần này chúng tôi tạo new int và chúng tôi chỉ cần sao chép giá trị của x (thông qua các tài liệu tham khảo). Int mới này có địa chỉ riêng của nó, nó không trỏ đến x như reference_to_x là.
reference_to_x = 5;
Chúng tôi giao x giá trị 5 thông qua các tài liệu tham khảo, và chúng tôi thậm chí không gọi hàm. copy_of_x không thay đổi.
copy_of_x = 15;
Chúng tôi đã thay đổi int mới để đánh giá 15. Các x không được thay đổi, kể từ copy_of_x có địa chỉ riêng của mình.
}
Như 6502 và những người khác chỉ ra, chúng tôi sử dụng phương pháp tương tự với trở về tài liệu tham khảo rất nhiều với container và ghi đè tùy chỉnh.
std::map<std::string, std::string> map = {};
map["hello"] = "Ahoj";
// is equal to
map.operator[]("hello") = "Ahoj"; // returns reference to std::string
// could be done also this way
std::string& reference_to_string_in_map = map.operator[]("hello");
reference_to_string_in_map = "Ahoj";
Chức năng bản đồ chúng tôi sử dụng có thể có tuyên bố như thế này:
std::string& map::operator[](const std::string& key); // returns reference
Chúng tôi không có địa chỉ để các chuỗi chúng ta "lưu trữ" trên bản đồ, vì vậy chúng ta gọi là chức năng ghi đè này của bản đồ , chuyển khóa đó để bản đồ biết chuỗi nào chúng ta muốn truy cập và nó trả về cho chúng ta tham chiếu đến chuỗi đó, mà chúng ta có thể sử dụng để thay đổi giá trị. CHÚ Ý: một lần nữa chức năng được gọi là đầu tiên và chỉ sau khi nó được hoàn thành (bản đồ tìm thấy chuỗi chính xác và tham chiếu trả về nó) nhiệm vụ xảy ra. Nó giống như với niềm vui() = 10, chỉ xinh đẹp hơn ...
Hope this helps bất cứ ai vẫn woudn't hiểu tất cả mọi thứ, ngay cả sau khi đọc câu trả lời khác ...
Trở tham chiếu đến biến tĩnh là vế trái (và hợp pháp). Tại sao bạn nghĩ rằng nên có bất kỳ lỗi nào? –
Giá trị trả về từ 'fun()' là 'int &' là 'lvalue' –
Đánh giá tham chiếu * kết quả trong * một giá trị. –