2008-10-15 31 views
49

[Câu hỏi này có liên quan đến nhưng không giống như this one.]!! một cách an toàn để chuyển đổi sang bool trong C + +?

Nếu tôi cố gắng sử dụng các giá trị của một số loại như biểu thức boolean, tôi nhận được một cảnh báo. Thay vì ngăn chặn cảnh báo, đôi khi tôi sử dụng toán tử bậc ba (?:) để chuyển đổi thành một bool. Sử dụng hai toán tử không (!!) dường như làm điều tương tự.

Đây là những gì tôi muốn nói:

typedef long T;  // similar warning with void * or double 
T t = 0; 
bool b = t;   // performance warning: forcing 'long' value to 'bool' 
b = t ? true : false; // ok 
b = !!t;    // any different? 

Vì vậy, không kỹ thuật đúp không thực sự làm điều tương tự? Nó có an toàn hơn nhiều so với kỹ thuật bậc ba không? Kỹ thuật này có an toàn không kém với các loại không tách rời (ví dụ: với void * hoặc double cho T)?

Tôi không hỏi nếu !!t là kiểu tốt. Tôi hỏi nếu nó có ngữ nghĩa khác với t ? true : false.

+3

Khi tôi nhìn thấy một dòng như "b = t đúng:? False;" Tôi luôn bị cám dỗ để thay thế nó bằng dòng "b = t". Đã có một diễn viên tiềm ẩn để bool, tại sao ngữ nghĩa mince? –

+2

như Q nói, bởi vì b = t đưa ra một cảnh báo – jwfearn

+2

thú vị có bao nhiêu người chống lại '!!' trên cơ sở chủ quan. đôi phủ định là * * thành ngữ-cast-bool xe trong JavaScript, và nếu javascripters nhận được nó, tôi mong đợi người dùng C++ cũng sẽ. –

Trả lời

83

Đối số của! toán tử và đối số đầu tiên của toán tử bậc ba được chuyển đổi hoàn toàn thành bool, vì vậy !! và?: là IMO trang trí ngớ ngẩn thừa của dàn diễn viên. Tôi bầu cho

b = (t != 0); 

Không chuyển đổi tiềm ẩn.

+4

Và cũng có thể đọc được. –

6

Tất cả các kỹ thuật hợp lệ, tất cả sẽ tạo cùng một mã.

Cá nhân, tôi chỉ tắt cảnh báo để tôi có thể sử dụng cú pháp rõ ràng nhất. Đúc cho một bool không phải là một cái gì đó tôi đang lo lắng về việc vô tình.

+4

Vâng, cảm ơn Microsoft đã cho chúng tôi cảnh báo về mã C rõ ràng và thành ngữ. –

+0

Tôi tự hỏi điều gì khiến họ thêm cảnh báo; ai đó chắc đã làm một cái gì đó * thực sự * câm ... –

+0

có lẽ nó có ý nghĩa đối với một số kiến ​​trúc mục tiêu nhất định? MS không nói khác hơn là cảnh báo cho phôi bình thường và chuyển đổi là "theo thiết kế" – jwfearn

41

Ngoài ra, bạn có thể làm điều này: bool b = (t != 0)

+4

Tôi luôn sử dụng cái này vì tôi nghĩ nó rõ ràng nhất thể hiện ý định. Đó là những gì trình biên dịch đang làm trong trường hợp tạo ra cảnh báo, nhưng rõ ràng về nó. Các !! có vẻ như là hacky với tôi. – rmeador

+0

Không hoạt động nếu t là đối tượng có lớp cung cấp toán tử (bool), trong khi các đề xuất khác thực hiện. – Jules

2

Nếu bạn đang lo lắng về cảnh báo, bạn cũng có thể buộc các diễn viên: bool b = (bool)t;

+1

thực sự tương đương với bool b = t; và tạo ra cùng một cảnh báo – jwfearn

+0

Không sử dụng C phôi. C++ phôi là có một lý do. Ngoài ra, tôi đã không thử điều này trên trình biên dịch của tôi, nhưng tôi sẽ không mong đợi nó để tạo ra bất kỳ cảnh báo bởi vì bạn đang yêu cầu một cách rõ ràng trình biên dịch để làm một cái gì đó. Trình biên dịch thường chỉ cảnh báo bạn khi có điều gì đó tiềm ẩn xảy ra. – wilhelmtell

+0

Tôi không bao giờ thấy cảnh báo theo GCC trên hộp Ubuntu của mình khi thực hiện theo cách này – warren

6


Có nó là an toàn.


0 được hiểu là sai sự thật, everthing khác là đúng,
vì thế! 5 đi ra như một sai
! 0 đi ra như đúng
quá !! 5 đi ra như đúng

1

!! có thể nhỏ gọn, nhưng tôi nghĩ nó phức tạp không cần thiết. Tốt hơn là vô hiệu hóa cảnh báo hoặc sử dụng toán tử bậc ba, theo ý kiến ​​của tôi.

-1

Đôi không cảm thấy buồn cười với tôi và trong mã gỡ lỗi sẽ rất khác so với mã được tối ưu hóa.

Nếu bạn yêu thích !! bạn luôn có thể Macro nó.

#define LONGTOBOOL(x) (!!(x)) 

(như một sang một bên, các nhà điều hành ternary là những gì tôi ủng hộ trong những trường hợp này)

3

Tôi khuyên bạn nên không bao giờ đàn áp cảnh báo đó, và không bao giờ sử dụng một dàn diễn viên c (bool) để ngăn chặn nó. Chuyển đổi có thể không phải lúc nào cũng được gọi như bạn giả định.

Có sự khác biệt giữa biểu thức đánh giá đúng và giá trị boolean của giá trị đó.

Cả hai !! và ternary nhận được sử dụng để, nhưng sẽ làm công việc tương tự, nếu bạn không muốn xác định các loại nội bộ với phôi quá tải để bool.

Cách tiếp cận của Dima cũng tốt, vì nó gán giá trị của biểu thức cho một bool.

+0

Hãy cẩn thận để đưa ra một ví dụ mà cảnh báo đó sẽ giúp ích cho bạn bằng bất kỳ cách nào? –

+0

tốt, bạn có thể đang mất thông tin trong dàn diễn viên đó. có thể bạn đang chuyển mã từ môi trường mà không có thông tin nào bị mất trong chuyển đổi này. trong trường hợp đó, bạn có thể muốn biết về bất kỳ bit bị mất nào. – wilhelmtell

+0

Tất nhiên bạn đang mất thông tin. Đó là toàn bộ điểm chuyển đổi thành bool! –

0

Tôi sẽ sử dụng b = (0! = T) - ít nhất bất kỳ người nào có thể đọc nó dễ dàng. Nếu tôi nhìn thấy đôi bên trong mã, tôi sẽ rất ngạc nhiên.

5

tôi sẽ không sử dụng:

bool b = !!t; 

Đó là cách ít nhất có thể đọc được (và do đó khó khăn nhất để duy trì)

Những người khác phụ thuộc vào tình hình.
Nếu bạn đang chuyển đổi để sử dụng chỉ trong biểu thức bool.

bool b = t ? true : false; 
if (b) 
{ 
    doSomething(); 
} 

Sau đó, tôi sẽ cho phép các ngôn ngữ làm điều đó cho bạn:

if (t) 
{ 
    doSomething(); 
} 

Nếu bạn đang thực sự lưu trữ một giá trị boolean. Sau đó, trước tiên tôi sẽ tự hỏi tại sao bạn có một lâu ở những nơi đầu tiên đòi hỏi các diễn viên. Giả sử bạn cần giá trị bool dài và tôi sẽ xem xét tất cả những điều sau tùy thuộc vào tình huống.

bool b = t ? true : false;  // Short and too the point. 
           // But not everybody groks this especially beginners. 
bool b = (t != 0);    // Gives the exact meaning of what you want to do. 
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning 
           // except as a bool in this context. 

Tóm tắt:. Sử dụng những gì cung cấp ý nghĩa nhất đối với bối cảnh bạn đang ở trong
Hãy thử và làm cho nó những gì rõ ràng bạn đang làm

+0

"cho phép ngôn ngữ làm điều đó" (aka 'chuyển đổi thông thường') là những gì tạo ra cảnh báo. một ví dụ về khi điều này có thể cần thiết: struct C {void * hdl; void * get_hdl() {trả về hdl; } bool has_hdl() const {return hdl? đúng sai; } – jwfearn

+7

khả năng đọc nằm trong mắt của người xem. ví dụ, tôi xem xét các toán tử tiền tố dễ đọc hơn các toán tử postfix, conciseness over verbosity, và dryness over duplication. (double) negation là một toán tử prefix (win), ngắn hơn ternary (win), và có thể được coi là một toán tử đơn trong khi ternary mang ba biểu thức riêng biệt (cộng với cú pháp toán tử). –

-4

Tôi sẽ sử dụng bool b = t và rời khỏi biên dịch cảnh báo trong, bình luận về sự an toàn của dòng cụ thể này. Việc tắt cảnh báo có thể khiến bạn bị kẹt ở mông trong một phần khác của mã.

+5

Để lại các cảnh báo cần được bỏ qua là phản tác dụng; nó dẫn bạn đến những cảnh báo khác, quan trọng hơn. Một chính sách không cảnh báo là tốt nhất. –

+0

Có, nhưng việc vô hiệu cảnh báo tệ hơn, nó sẽ tắt cảnh báo có thể quan trọng hơn. Như Edgar đã nói ở trên, bools là về giá trị chân lý, số nguyên là về số lượng. Sự khác biệt đó phải được bảo tồn bằng cách nào đó. –

-1

Tôi khuyên bạn nên sử dụng

nếu

hoặc

if (x = NULL!)

thay vì if (x) (x = 0); nó dễ hiểu hơn và dễ đọc hơn.

+2

Với tôi 'if (x)' dễ đọc hơn. Nó nói 'nếu không phải là zero' theo cách ngắn gọn nhất. –

31

Cẩn thận!

  • Boolean là về sự thật và sai.
  • Một số nguyên là về các số nguyên.

Đó là những khái niệm rất khác biệt:

  • Chân lý và sự sai lầm về quyết định thứ.
  • Số là về đếm nội dung.

Khi kết nối các khái niệm đó, cần được thực hiện một cách rõ ràng.Tôi thích phiên bản Dima của tốt nhất:

b = (t != 0);

Đó là mã nói rõ: So sánh hai số và lưu trữ các sự thật có giá trị trong một boolean.

2

Tôi thực sự ghét !! t !!!!!!. Nó có những điều tồi tệ nhất về C và C++, sự cám dỗ quá nửa thông minh với cú pháp của bạn.

bool b (t! = 0); // Là cách tốt nhất IMHO, nó cho thấy rõ ràng những gì đang xảy ra.

0

Tắt cảnh báo.

Viết để làm rõ trước; rồi hồ sơ; sau đó tối ưu hóa tốc độ, nếu cần.

0

!! chỉ hữu ích khi bạn đang sử dụng một biểu thức boolean trong thời trang số học, ví dụ .:

c = 3 + !!extra; //3 or 4 

(của ai phong cách là một cuộc thảo luận khác nhau.) Khi tất cả bạn cần là một biểu thức boolean, những !! là thừa. Viết

bool b = !!extra; 

làm cho càng nhiều ý nghĩa như:

if (!!extra) { ... } 
Các vấn đề liên quan