2012-05-10 66 views
5

Mã này có hợp lệ không?Biến đổi tạm thời C++ tạm thời

int foo() 
{ 
    std::vector<std::string>& v = std::vector<std::string>(5, "X"); 

    // Do something silly... 

    return 42; 
} 

Đối với một số lý do tôi nghĩ rằng tạm thời std::vector đối tượng (ngay từ dấu hiệu phân công) nên được destructed ngay sau đó là xây dựng (do đó vẽ tham chiếu không hợp lệ).

Tuy nhiên, gỡ lỗi chứng minh rằng tôi sai và, tốt, tôi nhận ra rằng tôi không hoàn toàn hiểu tại sao biến tạm thời bị hủy khi hàm trả về.


Tôi đoán tôi có một sự hiểu lầm mạnh mẽ của một cái gì đó cơ bản, vì vậy hãy soi sáng cho tôi :)

+0

Khi bạn nói "gỡ lỗi chứng minh rằng tôi sai", bạn có ý gì? –

Trả lời

8

Mã bạn đã thể hiện là bất hợp pháp – temporaries chỉ có thể liên kết với tài liệu tham khảo rvalue hoặc const tham chiếu lvalue.

VC++ xảy ra để cho phép tiện ích mở rộng (và cung cấp cho số a level 4 warning nói như vậy).

+1

gcc phàn nàn độc đáo về điều này: 'lỗi: khởi tạo không hợp lệ của tham chiếu không const của loại 'std :: vector , std :: allocator >, std :: allocator < std :: basic_string , std :: allocator >>> & 'từ tạm thời kiểu' std :: vector , std :: phân bổ >, std :: allocator , std :: allocator >>> ' – Scottymac

+0

Cảm ơn bạn, không biết về phần mở rộng đó * (và, tốt, nên ' đã thử 'gcc'). * –

+2

@ Yippie-Kai-Yay: Sau đó, bạn nên xây dựng với cảnh báo cấp 4 được bật. ; -] – ildjarn

2

Bạn có tham chiếu đến đối tượng được phân bổ. Nó hoạt động bằng 'may mắn tuyệt đối' (xem Ngôn ngữ lập trình C++, phần 10.4.10 Đối tượng tạm thời). Bạn không thể đảm bảo rằng nó sẽ làm việc trong mọi trình biên dịch.

Bạn chỉ có thể chắc chắn rằng thời gian tồn tại tạm thời được gia hạn nếu nó bị ràng buộc với tham chiếu const.

+2

Nó không phải là may mắn trong trường hợp này, nó là một phần mở rộng ngôn ngữ được cung cấp bởi trình biên dịch OP đang sử dụng. – ildjarn

+0

@ildjarn Tôi chỉ trích dẫn Stroustrup lưỡi-trong-má. Vấn đề là nó không di động/bất hợp pháp/không đáng tin cậy hoặc bất cứ điều gì bạn muốn gọi nó. – frozenkoi

+3

Nó không di động, đồng ý, nhưng nó cũng không phải là bất hợp pháp; tiêu chuẩn C++ (§1.4/8) đặc biệt cho phép mở rộng ngôn ngữ miễn là phần mở rộng không ảnh hưởng đến hành vi của mã được tạo đúng, và trình biên dịch đưa ra một chẩn đoán (số cảnh báo). – ildjarn

3

Thời gian hoạt động bình thường của tạm thời là cho đến khi kết thúc biểu thức đầy đủ mà nó được tạo; nó không nhất thiết phải bị hủy ngay lập tức khi sử dụng. Nếu tạm thời được sử dụng để khởi tạo tham chiếu, thì thời gian tồn tại của nó được mở rộng để khớp với tham chiếu (với ngoại lệ đáng chú ý của một tạm thời được tạo trong danh sách khởi tạo của một hàm tạo ).

Tất nhiên, mã của bạn là bất hợp pháp; nếu tham chiếu là không phải là const, thì chỉ có thể khởi tạo với một số loại giá trị. Nhưng nếu nó là hợp pháp (và ít nhất một trình biên dịch chấp nhận nó), tuổi thọ phải là được mở rộng để khớp với tham chiếu đó.