2013-08-07 30 views
20

Di chuyển không thể được triển khai hiệu quả (O (1)) trên std :: array, vậy tại sao nó lại có hàm khởi tạo?Nên std :: mảng có di chuyển constructor?

+8

'std :: array' không có bất kỳ nhà thầu * nào * ngoại trừ các giá trị mặc định do trình biên dịch tạo ra. – Casey

+1

Bạn lấy thông tin sai ở đâu (rằng 'std :: array' có một hàm tạo di chuyển)? –

+1

@ R.MartinhoFernandes trình tạo phương thức di chuyển do trình biên dịch tạo ra. – Walter

Trả lời

28

std::array có trình biên dịch di chuyển được tạo bởi trình biên dịch, cho phép tất cả các phần tử của một thể hiện được di chuyển sang một trường hợp khác. Đây là thuận tiện nếu các yếu tố này là một cách hiệu quả di chuyển hoặc nếu chúng chỉ là di chuyển:

#include <array> 
#include <iostream> 

struct Foo 
{ 
    Foo()=default; 
    Foo(Foo&&) 
    { 
    std::cout << "Foo(Foo&&)\n"; 
    } 
    Foo& operator=(Foo&&) 
    { 
    std::cout << "operator=(Foo&&)\n"; 
    return *this; 
    } 
}; 

int main() 
{ 
    std::array<Foo, 10> a; 
    std::array<Foo, 10> b = std::move(a); 
} 

Vì vậy, tôi sẽ nói std::array nên có một constructor di chuyển sao chép, đặc biệt kể từ khi nó đi kèm miễn phí. Không có ai yêu cầu nó bị vô hiệu hóa, và tôi không thể thấy bất kỳ lợi ích nào trong đó.

+0

Liệu nó có yêu cầu hàm khởi tạo phần tử là 'nothrow' không? Hoặc nó có thể chỉ đơn giản là để lại các hoạt động trong bất kỳ trạng thái pháp lý? –

+1

@MarkB câu hỏi hay, tôi đã không xem xét nó. Mã này hoạt động như trên gcc 4.7.3, ngay cả khi tôi thêm một hàm tạo bản sao. Tôi sẽ phải đọc tiêu chuẩn, nhưng dự đoán của tôi sẽ là việc di chuyển từ một container này sang một container khác không thể trông đợi để hỗ trợ bảo đảm ngoại lệ mạnh mẽ. – juanchopanza

+0

@juanchopanza: Tôi tin rằng bạn có quyền đảm bảo an toàn ngoại lệ. Đó là, 'std :: array' move-constructor không cung cấp sự bảo đảm an toàn ngoại lệ mạnh mẽ. Chỉ có cơ bản. Xem viên đạn đầu tiên của 12,8/15. Nghi ngờ duy nhất của tôi là nếu "subobject corrresponding" cũng là một rvalue. Bạn nghĩ sao? –

0

Có một cái nhìn tại các tiêu chuẩn: nhà xây dựng

23.3.2.2 mảng, sao chép và phân [array.cons]

Các điều kiện cho một số tổng hợp (8.5.1) sẽ được đáp ứng. Mảng lớp dựa vào các hàm thành viên đặc biệt được khai báo ngầm định (12.1, 12.4 và 12.8) để phù hợp với bảng yêu cầu vùng chứa trong 23.2. Ngoài các yêu cầu được chỉ định trong bảng yêu cầu vùng chứa, hàm khởi tạo ẩn và di chuyển gán cho toán tử cho mảng yêu cầu T là MoveConstructible hoặc MoveAssignable, tương ứng.

Nhà điều hành di chuyển và toán tử gán không được miễn phí, chúng có thể không được cung cấp.

23

Để tóm tắt và mở rộng câu trả lời khác, array<T> nên di chuyển (khi T chính nó là di chuyển) vì:

  • T có thể có hiệu quả di chuyển.
  • T có thể di chuyển- chỉ.
+0

lol, điều này không nói gì cả. "nên" "có thể" "có thể" ... ít nhất bạn có nghĩa là "nên" theo tiêu chuẩn? –

+0

@ v.oddou Đây là lý do tại sao thực tế là 'mảng ' ** là ** di chuyển (đối với T di động) có ý nghĩa. – juanchopanza

+0

@juanchopanza: đây chỉ là một bức thư cho Santa Claus. điều này đã rõ ràng trước câu hỏi. có, chúng tôi muốn những gì được nêu. bây giờ chúng tôi muốn biết ** sự thật ** về việc liệu nó có hay không, và tại sao. –

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