2013-11-09 13 views
6
loại

Chuẩn C++ như int hay char có ctors, vì vậy bạn có thể có biểu hiện như:Đi qua một biến ẩn danh bằng cách tham khảo

int a = int(67); // create anonymous variable and assing it to variable a 
int b(13);  // initialize variable b 
int(77);   // create anonymous variable 

Người dùng xác định loại (cấu trúc hoặc các lớp học) có thể làm tương tự:

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

STRUCT c = STRUCT(67); 
STRUCT d(13); 
STRUCT(77); 

Câu hỏi đặt ra là: tại sao chúng ta có thể chuyển qua cấu trúc ẩn danh tham chiếu hoặc phiên bản lớp, nhưng không thể vượt qua các loại tiêu chuẩn?

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

void func1(int& i){} 
void func2(STRUCT& s){} 
void func3(int i){} 
void func4(STRUCT s){} 

void main() 
{ 
    //func1(int(56)); // ERROR: C2664 
    func2(STRUCT(65)); // OK: anonymous object is created then assigned to a reference 
    func3(int(46)); // OK: anonymous int is created then assigned to a parameter 
    func4(STRUCT(12)); // OK: anonymous object is created then assigned to a parameter 
} 
+4

Dòng 'func2' của bạn không được biên dịch (vì lý do tương tự như đầu tiên). – Mat

+0

'void main()' không chuẩn. –

+0

Với mức cảnh báo thích hợp, bạn sẽ nhận được 'cảnh báo C4239: phần mở rộng không chuẩn được sử dụng: 'đối số': chuyển đổi từ 'STRUCT' thành 'STRUCT &'; Tham chiếu không phải const chỉ có thể được liên kết với một giá trị '. Bạn nên sử dụng '/ W4'. –

Trả lời

2

Nếu trình biên dịch của bạn cho phép điều này, thì trình biên dịch C++ không tương thích chuẩn. Bạn không thể liên kết một giá trị tạm thời với tham chiếu không phải lvalue. Đó là quy tắc. Cả hai clanggcc không biên dịch mã đó cho func2(STRUCT(65));.

Thay vào đó bạn có lựa chọn thay thế:

void func1(int&& i){} 

void func1(const int& i){} 

Legacy từ C++ 03: A (vế trái) tham chiếu đến một loại không const (int &i) phải có khả năng thay đổi các tham số sau đó đi qua một đối tượng tạm thời như vậy như 56 không hợp lý vì nó không thể thay đổi. Tham chiếu đến loại const (const int &i) chỉ cần quan sát giá trị là chỉ đọc, sau đó chuyển một giá trị tạm thời như 52 là hợp pháp.

Trong C++ 11, bạn có thể tham chiếu đến đối tượng tạm thời không phải là const bằng &&.

5

Dường như bạn đang sử dụng trình biên dịch MS VC++ có lỗi như vậy. :) Bạn phải liên kết đối tượng tạm thời với tham chiếu const. Ví dụ, bạn có thể viết

const int &ri = 10; 

nhưng bạn có thể không viết

int &ri = 10; 

Điều này cũng có giá trị với nhiều loại người dùng định nghĩa.

const STRUCT &rs = STRUCT(10); 

STRUCT &rs = STRUCT(10); // the compiler shall issue an error. 
0

Trong C++, một đối tượng tạm thời mang tính chất luôn luôn là một right-value.To chấp nhận một quyền có giá trị như là đối số, bạn có thể:

1) foo1 .void (TYPE); // chuyển theo giá trị
2) .void foo2 (const TYPE &); // chuyển bằng tham chiếu const
3) .void foo3 (TYPE & &); // trong C++ 11, chuyển qua tham chiếu giá trị phải

"Func3" và "func4" của bạn chấp nhận một đối số được truyền theo giá trị, không sao cả.
Tuy nhiên, "func1" và "func2" chỉ có thể chấp nhận đối số được chuyển bởi tham chiếu giá trị bên trái. Do đó, sai khi chuyển một tham số ẩn danh.

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