2016-10-07 13 views
6

tôi thấy GCC 7 đã thực hiện đảm bảo bản sao sự bỏ bớt, và tôi đã cố gắng mã dưới đây vào wandbox:Đảm bảo sự bỏ bớt sao chép và Nonmoveable {Nonmoveable {}}

#include <iostream> 

struct NonMovable 
{ 
    NonMovable() noexcept = default; 
    NonMovable(NonMovable&&) noexcept = delete; 
    NonMovable& operator=(NonMovable&&) noexcept = delete; 
}; 

NonMovable Make() 
{ 
    return {}; 
} 


int main() 
{ 
    //[[maybe_unused]] const auto x = Make(); 
    //const auto z = NonMovable{}; 
    [[maybe_unused]] const auto y = NonMovable{NonMovable{}}; 
} 

Và tôi đã biên dịch báo lỗi:

prog.cc: In function 'int main()': 
prog.cc:20:60: error: use of deleted function 'NonMovable::NonMovable(NonMovable&&)' 
    [[maybe_unused]] const auto y = NonMovable{NonMovable{}}; 
                  ^
prog.cc:6:5: note: declared here 
    NonMovable(NonMovable&&) noexcept = delete; 
    ^~~~~~~~~~ 

Theo cppreference:

In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:
T x = T(T(T())); // only one call to default constructor of T, to initialize x

Vì vậy, tôi nghĩ rằng nó phải equ al đến const Movable y{};. Chuyện gì vậy?

+0

Dường như đó là lỗi của GCC. Mã này biên dịch tốt trên một bản xây dựng mới của GCC. – Cu2S

Trả lời

1

Việc khởi tạo danh sách cho phép bạn không kiểm soát chính xác những gì sẽ xảy ra. Về cơ bản, ủy ban đã đoán được lập trình viên có thể muốn làm gì nhiều nhất và có thể gán các ý nghĩa tương ứng.

Nếu bạn muốn có quyền kiểm soát chính xác, hãy sử dụng khởi tạo không phải danh sách. Đối với điều đó, testcase của bạn nên làm việc chắc chắn.

Nếu bạn dính vào niêm yết-khởi, sau đó cho uẩn, tôi nghĩ hiện tại dự thảo từ ngữ sẽ làm điều đó và áp dụng được bảo đảm bản sao "sự bỏ bớt", bởi vì họ nói

If T is an aggregate class and the initializer list has a single element of type cv U, where U is T or a class derived from T, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization).

Bên cạnh đó, bạn sức nhận được những gì bạn muốn trong bản sửa đổi tương lai của Chuẩn hoặc trong một bản phân tích báo cáo lỗi ngay cả đối với những người không phải là tổng hợp. Tôi tin rằng lớp học của bạn là một tổng hợp, vì vậy nó nên biên dịch. Nhưng có lẽ có một cái gì đó tôi đang thiếu ở đây.

+1

"sử dụng khởi tạo không phải danh sách." Sẽ là 'const auto y = NonMovable (NonMovable());'? Nếu vậy, điều đó dường như không hoạt động. –

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