2010-04-22 34 views
6

Tại sao có hàm khởi tạo di chuyển hoặc toán tử gán mặc định không được tạo cho các lớp dẫn xuất? Để chứng minh những gì tôi có ý nghĩa; có mã thiết lập này:Di chuyển hàm tạo và toán tử gán: tại sao không mặc định cho các lớp dẫn xuất?

#include <utility> 

struct A 
{ 
    A() { } 
    A (A&&) { throw 0; } 
    A& operator= (A&&) { throw 0; } 
}; 

struct B : A 
{ }; 

một trong những dòng sau ném:

A x (std::move (A()); 
A x; x = A(); 

nhưng không phải điều nào sau đây không:

B x (std::move (B()); 
B x; x = B(); 

Trong trường hợp vấn đề, tôi đã thử nghiệm với GCC 4.4 .

EDIT: Thử nghiệm sau với GCC 4.5 cho thấy cùng một hành vi.

+1

Liệu 'std :: move' có thay đổi gì ở đây không? Không phải là 'A() 'đã là một giá trị? –

+0

Vâng, đúng vậy. Nếu không, tiêu chuẩn C++ cho phép trình biên dịch nén thành chỉ-xây dựng-x (hoặc vì vậy tôi đã nói trên freenode.net). Tôi cũng đã xác minh rằng không có 'std :: move', hàm tạo di chuyển không phải là trigerred, vì vậy nhận xét của freenode.net có vẻ đúng. – doublep

+2

@Mike: Sao chép elision (12.8/34, 0x FCD) là một tối ưu hóa phổ biến, nhưng bằng cách sử dụng move() làm cho biểu thức này nằm ngoài các trường hợp cho phép. –

Trả lời

6

Đọc qua 12.8 trong FCD 0x (cụ thể là 12.8/17 cho ctor di chuyển), đây có vẻ là lỗi GCC. Tôi thấy điều tương tự xảy ra trong 4.5 như bạn làm trong 4.4.

Tôi có thể thiếu trường hợp góc trên các chức năng đã bị xóa hoặc một chức năng tương tự, nhưng tôi chưa thấy bất kỳ dấu hiệu nào về điều đó.

+0

Chỉ cần thử nghiệm với 4.5, tôi nhận được kết quả tương tự. Bạn có thể thử nghiệm trên bất kỳ trình biên dịch nào khác không? (Cho rằng C++ 0x là không có cách nào hoàn thành, nó có thể không phải là một lỗi mà là một hành vi lỗi thời, bằng cách này.) – doublep

+3

Một loạt các công cụ trong 12,8 (bắt nguồn từ N3053) không được hỗ trợ trong 'gcc' tuy nhiên, theo trang hỗ trợ [C++ 0x] của họ (http://gcc.gnu.org/projects/cxx0x.html) - đây có phải là vấn đề không? –

+0

@Mike: Có vẻ như vậy, vâng. –

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