2008-09-17 26 views

Trả lời

16

1: Không cho phép địa chỉ tạm thời. Visual C++ cho phép nó như là một phần mở rộng ngôn ngữ (mở rộng ngôn ngữ được bật theo mặc định).

2: Điều này hoàn toàn hợp pháp.

+1

nó bị cấm để lấy địa chỉ của một rvalue, không phải là tạm thời cụ thể. đó là lý do tại sao điều này bị cấm; 'A()' trả về một giá trị. –

+2

@underscore_d Đúng - Tôi đã sử dụng cụm từ không chính thức 'tạm thời', cụ thể hơn là biến tạm thời chưa được đặt tên và, như bạn nói đúng, một giá trị. Nếu chúng ta đang kén chọn, 'A()' không 'trả về' một giá trị (các hàm tạo không có giá trị trả về), đó là một biểu thức giá trị. –

+0

Tốt bắt - đó là quá dễ dàng để theo phản xạ suy nghĩ của các nhà thầu như các cuộc gọi chức năng. –

-2

hoàn toàn hợp pháp.

Đối tượng sẽ tồn tại trên ngăn xếp trong khi gọi hàm, giống như bất kỳ biến cục bộ nào khác.

0

Nó trông lke nó sẽ làm việc, nhưng nó không biên dịch với g ++ với các tùy chọn tường, đây là những gì tôi nhận được:

 
[email protected]:~/Desktop$ g++ -Wall a.cpp 
a.cpp: In function ‘int main()’:[email protected]:~/Desktop$ g++ -Wall a.cpp 
a.cpp: In function ‘int main()’: 
a.cpp:8: warning: taking address of temporary 
a.cpp:9: error: invalid initialization of non-const reference of type ‘A&’ from a temporary of type ‘A’ 
a.cpp:4: error: in passing argument 1 of ‘void bar(A&)’ 
[email protected]:~/Desktop$ 

Hình như bạn sẽ cần phải sử dụng một tham chiếu liên tục.

+0

Nhưng thực tế là cả cảnh báo về vấn đề MSVC và g ++ cho (1) cho thấy rằng nó có thể không được 100% hợp pháp. Bạn có một phần của trích dẫn tiêu chuẩn C++ không? –

1

Những đối tượng đó sẽ chỉ tồn tại cho đến khi thực hiện đạt đến dấu chấm phẩy. Vì vậy, các cuộc gọi được an toàn, nhưng không cố gắng để lưu con trỏ và sử dụng nó sau này. Ngoài ra, trình biên dịch có thể yêu cầu thanh lấy tham chiếu const.

+0

'foo (& A()) có thể là" an toàn ", _if_ nó biên dịch. Nó không hợp lệ C++. –

-1

Điều đó là hợp pháp. Chúng tôi sử dụng nó đôi khi để cung cấp một giá trị mặc định mà chúng tôi có thể muốn bỏ qua.

int dosomething(error_code& _e = ignore_errorcode()) { 
    //do something 
} 

Trong trường hợp trên nó sẽ tạo đối tượng mã lỗi trống nếu không có error_code được chuyển đến hàm.

+0

Tôi chắc chắn rằng ignore_errorcode của bạn() trả về một đối tượng error_code với một số đời hơn một đối tượng được tạo bởi một hàm tạo mặc định ... – Pieter

-1

cho // 2 bạn cần một tham chiếu const

cho // 1 Tôi nghĩ rằng đó là hợp pháp nhưng vô ích

+0

Không, 'foo (& A())' là _not_ hợp pháp vì 'A()' là một rvalue, và bạn không thể lấy địa chỉ của một rvalue. http://stackoverflow.com/a/2985578/2757035 –

9

Không, nó chống lại tiêu chuẩn để vượt qua một tham chiếu không const đến một đối tượng tạm thời. Bạn có thể sử dụng một tham chiếu const:

class A{}; 

void bar(const A&); 

int main(void) 
{ 
    bar(A()); // 2 
} 

Vì vậy, trong khi một số compliers sẽ chấp nhận nó, và nó sẽ làm việc càng lâu càng không sử dụng bộ nhớ sau khi các dấu chấm phẩy, một trình biên dịch phù hợp sẽ không chấp nhận nó.

+4

Câu trả lời này đã lỗi thời bởi một chỉnh sửa của OP –

5

foo không được phép tuân thủ đầy đủ tiêu chuẩn C++, trong khi thanh vẫn ổn. Mặc dù cơ hội là, foo sẽ biên dịch với cảnh báo và thanh có thể hoặc không thể biên dịch bằng cảnh báo.

A() tạo ra một đối tượng tạm thời, trong đó trừ khi bị ràng buộc vào một tài liệu tham khảo (như trường hợp ở thanh), hoặc sử dụng để khởi tạo một đối tượng có tên, bị phá hủy vào cuối của biểu thức đầy đủ trong đó Nó đã được tạo ra. Một tạm thời được tạo ra để giữ một bộ khởi tạo tham chiếu vẫn tồn tại cho đến khi kết thúc phạm vi tham chiếu của nó.Đối với trường hợp của thanh, đó là lệnh gọi hàm, do đó bạn có thể sử dụng A bên trong thanh hoàn toàn an toàn. Nó bị cấm để ràng buộc một đối tượng tạm thời (đó là một rvalue) để tham chiếu không const. Nó tương tự bị cấm để lấy địa chỉ của một rvalue (để chuyển làm đối số để khởi tạo A cho foo).

+0

Cần một số tái cấu trúc để làm rõ phạm vi nâng cao khả năng của một referene trên một biến tạm thời. –

+0

Đây là câu trả lời vượt trội bởi vì nó được nó đúng là những gì bị cấm là lấy địa chỉ của một rvalue - không phải là một tạm thời cụ thể. –

2

Câu trả lời ngắn gọn là có.

Nếu đối tượng được nhận bởi hàm như tham số tham chiếu const - khi bạn đã sửa đổi phương thức bar(const A&), thì nó hoàn toàn hợp pháp. Hàm có thể hoạt động trên đối tượng, nhưng đối tượng sẽ bị hủy sau khi cuộc gọi hàm (địa chỉ tạm thời có thể được thực hiện, nhưng sẽ không được lưu trữ và sử dụng sau khi gọi hàm - xem lý do bên dưới).

foo(A*) cũng hợp pháp vì đối tượng tạm thời bị hủy khi kết thúc ghi hình. Tuy nhiên hầu hết các trình biên dịch sẽ phát ra cảnh báo về việc lấy địa chỉ tạm thời.

Phiên bản gốc của bar(A&) không được biên dịch, nó không phù hợp với tiêu chuẩn để khởi tạo tham chiếu không const từ tạm thời.

chuẩn C++ chương 12,2

3 [...] đối tượng tạm thời bị phá hủy như là bước cuối cùng trong việc đánh giá các fullexpression (1.9) mà (giải nghĩa từ vựng) chứa các điểm mà họ đã tạo ra. [...]

4 Có hai ngữ cảnh trong đó thời gian tạm thời bị hủy tại một điểm khác với điểm kết thúc của quá trình nén. Ngữ cảnh đầu tiên là khi một biểu thức xuất hiện như một bộ khởi tạo cho một người khai báo xác định một đối tượng. Trong bối cảnh đó, tạm thời giữ kết quả của biểu thức sẽ vẫn tồn tại cho đến khi khởi tạo của đối tượng hoàn tất. [...]

5 Ngữ cảnh thứ hai là khi tham chiếu bị ràng buộc tạm thời. Tạm thời mà tham chiếu bị ràng buộc hoặc tạm thời là đối tượng hoàn chỉnh đối với một đối tượng con trong đó tạm thời bị ràng buộc tồn tại trong suốt thời gian tồn tại của tham chiếu ngoại trừ được chỉ định bên dưới. Một ràng buộc tạm thời cho một thành viên tham chiếu trong ctorinitializer của một hàm tạo (12.6.2) vẫn tồn tại cho đến khi hàm khởi tạo xuất hiện. Một ràng buộc tạm thời với tham số tham chiếu trong một cuộc gọi hàm (5.2.2) vẫn tồn tại cho đến khi hoàn thành biểu thức đầy đủ có chứa cuộc gọi. Một ràng buộc tạm thời với giá trị trả về trong câu lệnh trả về hàm (6.6.3) vẫn tồn tại cho đến khi hàm thoát.

A fullexpression là một biểu thức không phải là biểu hiện của một biểu thức khác.

+0

Không, 'foo (& A())' là _not_ hợp pháp vì 'A()' là một giá trị, và bạn không thể lấy địa chỉ của một giá trị. http://stackoverflow.com/a/2985578/2757035 –

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