2011-02-07 38 views
13

Làm cách nào để ngăn dòng cuối cùng của mã này được biên dịch?Chuyển đổi tăng :: tùy chọn để bool

#include <boost/optional.hpp> 

int main() 
{ 
    typedef boost::optional<int> int_opt; 
    int_opt opt = 0; 
    bool x = opt; // <- I do not want this to compile 
} 

Dòng cuối cùng không kiểm tra opt 's chứa giá trị int, nhưng thay vì biên dịch như một loại chuyển đổi đến bool, và dường như không có gì mà người dùng mong muốn.

Thành ngữ bool an toàn có vẻ có liên quan ở đây?

+4

Ý bạn là gì _something like_? Mô tả bằng tiếng Anh những gì bạn muốn. Mã rõ ràng không mô tả những gì bạn muốn. Vậy làm thế nào chúng ta nên biết? – Oswald

+1

bạn không thể, 'boost :: optional' thực thi' toán tử 'và đây là lý do tại sao dòng cuối cùng ở trên biên dịch. Bạn thậm chí không thể lấy được từ điều này để ẩn nhà điều hành đó - bạn cần phải sửa mã của bạn. – Nim

Trả lời

16

Toàn bộ các điểm boost::optional là cho phép mã như thế này:

void func(boost::optional<int> optionalArg) 
{ 
    if (optionalArg) { 
     doSomething(*optionalArg); 
    } 
} 

Vì vậy, việc chuyển đổi ngầm để bool là một tính năng, và không nên được ngăn chặn từ biên soạn.

+0

Đây không phải là những gì thành ngữ bool an toàn cố gắng giải quyết? (http://www.artima.com/cppsource/safebool.html) – dimba

+3

@dimba: Thành ngữ bool an toàn tự nhiên không ngăn cản việc sử dụng giá trị theo ngữ cảnh thuần túy. – UncleBens

+0

@UncleBens - thực sự, thay đổi x loại trong dòng cuối cùng từ bool thành int gây ra lỗi biên dịch. – dimba

1

Nếu bạn đang sử dụng optional thì bạn cần có khả năng xác định xem nó có được đặt trước khi sử dụng hay không. Cách này được thực hiện là với (hiệu quả bool) chuyển đổi.

Tôi không nghĩ rằng người dùng không muốn những gì thực sự được viết ở đó: Họ nên biết rằng đó là một số optional và họ đang kiểm tra tính hợp lệ của nó.

Vì chuyển đổi được xây dựng một phần của boost::optional Tôi không biết bất kỳ cách nào để xóa trực tiếp.

Tất nhiên bạn có thể triển khai lớp bao bọc cho int chỉ cần cung cấp các phần của giao diện optional mà bạn muốn, có thể với chức năng rõ ràng kiểm tra tính hợp lệ.

Cách khác bạn luôn có thể sử dụng template<class T> inline T const* get_pointer (optional<T> const& opt) ; hoặc phiên bản không const của nó khi làm việc với optional để làm rõ điều gì đang xảy ra.

1

Sự cố mà bạn mô tả được sử dụng là trường hợp đối với các phiên bản Boost cũ hơn. Kể từ khi phát hành 1,56 boost::optional có chuyển đổi rõ ràng thành bool và mã mà bạn hiển thị không biên dịch nữa (chính xác theo cách bạn muốn). See here.

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