2011-10-22 25 views
11

Có mã như:Thay đổi giá trị trở lại của loại cơ bản và kiểu lớp

#include <iostream> 
#include <string> 

int returnnumber() { return 2; } 
std::string returntext() { return "siema"; } 

int main() { 

    std::cout << (returntext() += "cze") << std::endl; // siemacze 
    //std::cout << (returnnumber() += 2) << std::endl; error: lvalue required as left operand of assignment 

    return 0; 
} 

Tại sao là nó có thể thay đổi giá trị trả về của std :: string, nhưng không phải int?

Trả lời

10

std::string là loại lớp có toán tử được xác định là += là hàm thành viên.

và tiêu chuẩn cho phép bạn gọi hàm thành viên trên giá trị.

một hậu quả ngớ ngẩn đó là

struct S { int x; }; 
S foo() { return S(); } 

int main() 
{ 
    foo() = S(); // OK, uses member assignment operator. 
    foo().x = 666; // !Nah, can't assign to rvalue of built-in type. 
} 

biên soạn kết quả:

 
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 
Copyright 1988-2008 Comeau Computing. All rights reserved. 
MODE:strict errors C++ C++0x_extensions 

"ComeauTest.c", line 7: error: expression must be a modifiable lvalue 
     foo().x = 666; // !Nah, can't assign to rvalue of built-in type. 
    ^

1 error detected in the compilation of "ComeauTest.c". 

tuy nhiên, trình biên dịch khác nhau (hoặc sử dụng để khác nhau) về cách nghiêm họ đã áp dụng quy tắc tinh tế này, hoặc nếu có.

cổ vũ & h.,

+0

Vâng, nhưng đối với 'int' toán tử' + = 'cũng được xác định. – Vlad

+0

@downvoter: Tại sao? – Vlad

+0

@ downlist downmaner: xin vui lòng giải thích downvote của bạn để những người khác có thể được hưởng lợi từ cái nhìn sâu sắc của bạn, hoặc bỏ qua một số lý do ngu ngốc. –

2

Phía tay trái của một toán tử gán cho một built-in loại phải đạt được một sửa đổi vế trái nhưng giá trị trả về của một hàm phải lúc nào cũng một rvalue nếu chức năng không trả lại loại tham chiếu.

operator+= là chức năng thành viên của std::string và bạn có thể gọi hàm thành viên theo số rvalue loại lớp.

+0

Tôi tự hỏi, tại sao sự mâu thuẫn này lại như vậy? – Vlad

+0

Ý của bạn là "bên tay trái của toán tử gán?" –

+0

@VaughnCato: Vâng, tôi đã làm. Cảm ơn. –

1

Đối với lý do tương tự

std::string("siema") += "cze"; 

công trình.

Bạn đang xây dựng một đối tượng mới và áp dụng operator += (trong đó std::string có) cho nó.

Thử cách này với nó sẽ không hoạt động khi hàm của bạn trả về một rvalue. Nó sẽ như thế nào:

2 += 2 

Bạn có đồ chơi xung quanh với điều này:

#include <iostream> 
#include <string> 

int& returnnumber() { int * k = new int; *k = 2; return *k; } 
std::string returntext() { return "siema"; } 

int main() { 

    std::cout << (returntext() += "cze") << std::endl; // siemacze 
    std::cout << (returnnumber() += 2) << std::endl; //no error 
    std::string("siema") += "cze"; 
    return 0; 
} 

Nhưng điều này sẽ dẫn đến rò rỉ bộ nhớ, do đó, không làm điều đó. Nó chỉ là một bằng chứng về khái niệm trả lại một lvalue sẽ hoạt động.

+0

Hi Luchian :) Không 'returntext' trả về một giá trị không? – Vlad

+0

Charles Bailey đã viết: nhưng giá trị trả về của hàm luôn là giá trị nếu hàm không trả về kiểu tham chiếu. Sau đó returntext trả về rvalue hoặc lvalue? – scdmb

+0

Tôi đang bối rối, tắt để làm một số đọc :) –

0

returntext() trả lại số std::string có thể được sửa đổi trong các giai đoạn sau với nội dung là +=operator. Tuy nhiên, mặc dù returnnumber() trả về một int, bản thân hàm sẽ trả lại 2 bằng defualt a const int và không thể thay đổi và đó là lý do trình biên dịch phàn nàn.

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