2011-08-25 31 views
8
string foo() { return "hello"; } 
int main() 
{ 
    //below should be illegal for binding a non-const (lvalue) reference to a rvalue 
    string& tem = foo(); 

    //below should be the correct one as only const reference can be bind to rvalue(most important const) 
    const string& constTem = foo(); 
} 
  1. GCC là một tốt để cung cấp cho một lỗi biên dịch: khởi tạo không hợp lệ tham chiếu không const loại std::string& từ một tạm thời loại std::string
  2. VS2008 không phải là quá xấu như ít nhất nó mang lại một biên dịch cảnh báo: C4239 cảnh báo: mở rộng không chuẩn được sử dụng: 'khởi': chuyển đổi từ std::string để std::string & một không const tham khảo chỉ có thể được liên kết với một giá trị trái
  3. Ở đây có vấn đề một - VS2010 (SP1) comples tốt KHÔNG CÓ bất kỳ lỗi hoặc cảnh báo, TẠI SAO ?? !! Tôi biết tham chiếu rvalue trong VS2010 có thể được sử dụng để liên kết với rvalue nhưng tôi KHÔNG sử dụng &&, thay vào đó trong mã demo, tôi chỉ sử dụng tham chiếu không phải lvalue!

Ai đó có thể giúp tôi giải thích hành vi của VS2010 tại đây không? Nó là một lỗi! Cảm ơnMột lỗi VS2010? Cho phép tham chiếu không ràng buộc liên quan đến rvalue KHÔNG CÓ SỰ BÁO CÁO?

+1

thiết lập cảnh báo của bạn là gì? Có lẽ đó là cấu hình của bạn mà thay đổi, và không thực hiện của họ? –

+0

Tôi đã sử dụng VS2008 trong một thời gian nhưng gần đây đã cài đặt VS2010 nên VS10 nên sử dụng thiết lập mặc định ... – Gob00st

+2

thì tôi sợ rằng ngưỡng cảnh báo đơn giản là không đủ cao. Sử dụng '\ W4' để kích hoạt cảnh báo trong phạm vi' 4xxx'. –

Trả lời

11

Đó là sự cố/tính năng đã biết của trình biên dịch VS. Họ luôn cho phép điều đó và dường như không có bất kỳ sự xúc tiến nào trong việc xóa phần mở rộng đó.

+0

Bất kỳ ý tưởng nào tại sao MS cho phép sử dụng C++ bất hợp pháp này ngay từ đầu? Quy tắc tham chiếu cụ thể này phải khá cũ (98 hoặc 03 tiêu chuẩn)? – Gob00st

+0

@ Gob00st: đây là một phần mở rộng làm giảm giới hạn C++ tùy ý. Tôi là cá nhân của tâm rằng ràng buộc nên được cho phép hoặc không được phép và rằng hiện tại * một nửa cho phép * thực sự là một nhà nước vụng về. Không được phép hoàn toàn sẽ loại bỏ toàn bộ một lớp lỗi, mặc dù nó sẽ gây đau đớn, Được phép hoàn toàn sẽ làm thẳng các thông số kỹ thuật. –

+2

@ Gob00st - MS có một số mã cũ đã được viết trước khi các quy tắc đã được sửa (và do đó khách hàng của họ có thể có).Họ tin rằng điều quan trọng hơn là hỗ trợ mã cũ hơn các tiêu chuẩn mới. Cũng có thể tắt các phần mở rộng (và do đó không thể biên dịch một số tiêu đề Windows). –

9

Trình biên dịch sẽ phát hành lỗi với Tắt tiện ích mở rộng ngôn ngữ đã bật và cảnh báo tại/W4. Tuy nhiên, việc loại bỏ mã này sẽ phá vỡ mã biên dịch trước đó và Microsoft rất miễn cưỡng thực hiện điều đó. Đây cũng là lý do tại sao họ sẽ không sửa chữa hỗ trợ SFINAE của họ.

+0

Có thể đáng nói là cảnh báo đã được chuyển từ/W3 đến/W4 trong VS2010. – rustyx

-1

Có một biến thể nastier phần lớn vấn đề này:

Vì vậy: để những gì hiện b.f điểm trong suốt cuộc gọi đến b.F()? Ví dụ trên, được biên dịch với cài đặt gỡ lỗi mặc định của VS2013, chạy mà không gặp sự cố và in 3, nhưng tôi nghi ngờ rằng bất kỳ ví dụ phức tạp hơn nào cũng sẽ dẫn đến ngăn xếp tham nhũng. Nếu không và trình biên dịch đang làm một cái gì đó 'thông minh' để làm cho nó hoạt động, sau đó tôi đoán những gì nó thực sự được làm điều này là:

class Foo { 
    int _val; 
public: 
    Foo(int v) : _val(v) {} 
    void F() { std::cout << _val << std::endl; } 
}; 

class Bar { 
    Foo f; 
public: 
    Bar(Foo&& f) : f(f) {} 
    void F() { f.F(); } 
}; 

int main() { 
    Bar b(Foo(3)); 
    b.F(); 
} 
+0

Lưu ý rằng cùng một vấn đề này tồn tại nếu 'f' là tham chiếu const thay vào đó, và điều đó sẽ được cho phép theo tiêu chuẩn. –

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