2013-07-06 31 views
13

xem xét ví dụ sau đây, chúng tôi phân tích dữ liệu và thông qua kết quả với chức năng tiếp theo:Làm thế nào để chuyển từ std :: tùy chọn <T>

Content Parse(const std::string& data); 
void Process(Content content); 

int main() 
{ 
    auto data = ReadData(); 
    Process(Parse(data));  
} 

Bây giờ chúng ta hãy thay đổi mã sử dụng std::optional để xử lý một bước phân tích thất bại:

optional<Content> Parse(const std::string& data); 
void Process(Content content); 

int main() 
{ 
    auto data = ReadData(); 
    auto content = Parse(data); 
    if (content) 
     Process(move(*content)); 
} 

Có hợp lệ để di chuyển từ optional<T>::value() không? Nếu nó là ok cho std::optional nó có hợp lệ cho boost::optional không?

+0

Tôi nghĩ điều này sẽ ổn. Giá trị được chứa phải ở trạng thái hợp lệ nhưng không xác định sau khi di chuyển từ giá trị đó. –

Trả lời

9

Nó hợp lệ để di chuyển từ optional<T>::value() vì nó trả về một tham chiếu có thể thay đổi và di chuyển không phá hủy đối tượng. Nếu cá thể optional không phải là , hãy tham gia, value() sẽ ném một ngoại lệ bad_optional_access (§20.6.4.5).

Bạn rõ ràng kiểm tra xem tùy chọn là tham gia:

if (content) 
    Process(move(*content)); 

Nhưng bạn không sử dụng các thành viên value() để truy cập T cơ bản. Lưu ý rằng value() thực hiện kiểm tra nội bộ trước khi trả về T& hợp lệ, không giống như operator* trong đó có điều kiện tiên quyết điều kiện tiên quyết rằng phiên bản optional phải được thực hiện. Đây là một sự khác biệt tinh tế, nhưng bạn sử dụng thành ngữ đúng:

if (o) 
    f(*o) 

như trái ngược với

if (o) // redundant check 
    f(o.value()) 

Trong Boost, tình hình là một chút khác nhau: thứ nhất, có tồn tại không có chức năng thành viên được gọi là value() rằng cung cấp quyền truy cập đã chọn. (Một ngoại lệ bad_optional_access chỉ đơn giản là không tồn tại). Thành viên get() chỉ là bí danh cho operator* và luôn dựa vào người dùng kiểm tra xem trường hợp optional có tương tác hay không.

+0

Liệu toán tử '* có quá tải tham chiếu rvalue? Tức là, 'f (* std :: move (o))' - điều đó có di chuyển không? Tôi cũng mong là như vậy! – Yakk

+0

Tôi không thể tìm thấy một trong [tiêu chuẩn] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf). Hãy xem §20.6.4 trên trang 505 nơi giao diện được mô tả. – mavam

+1

Hmm. 'value_or' có quá tải' && 'và' & '. 'giá trị' không (Tại sao không? Naively, nên). Tôi có thể thấy không muốn một toán tử '&&' '*' trong trường hợp mọi người bị cám dỗ vào '*' mà không kiểm tra nếu 'tùy chọn' được gắn trước, nhưng với việc ném' giá trị' tôi không thể thấy được sự tổn hại? – Yakk

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