The Visual C ++ compiler warns of conversion to bool
, but with a dumb performance warning. This is usually an undesirable warning, but unfortunately it cannot be silenced by a simple work. An almost idiom for silence is to use double negation !!
bang-bang e.g. return !!0.0
.
Your problem is the opposite, that you want to receive such a warning or error, but nevertheless an almost-idiom error can be part of the solution.
With the example below, you simply write bool
instead of bool
where you want to have a boolean, and use !!
to ensure clean bool
values, otherwise you will get compilation errors.
The best part is that, most likely, you can just do a global search and replace it in your code by replacing bool
with bool
.
#ifdef CLEAN # define TO_BOOL !! #else # define TO_BOOL #endif #define STATIC_ASSERT( e ) static_assert( e, #e ) #include <type_traits> // std::is_same #include <utility> // std::enable_if_t class Bool { private: bool value_; public: operator bool() const { return value_; } template< class T , class Enabled_ = std::enable_if_t<std::is_same<T,bool>::value, void> > auto operator=( T const other ) -> Bool& { value_ = other; return *this; } Bool(): value_() {} template< class T , class Enabled_ = std::enable_if_t<std::is_same<T,bool>::value, void> > Bool( T const value ) : value_( value ) {} }; auto f() -> double { return 0.0; } auto something() -> Bool { return TO_BOOL 0.0; } // ← Line 43 auto g() -> double { Bool x = TO_BOOL 0.0; // ← Line 48 if (something()) { x = TO_BOOL f(); // where f() is a function returning a double } return x; } auto main() -> int { Bool a, b, c; return a && b || something(); }
Compilation examples with g ++:
c: \ my \ forums \ so \ 105> g ++ foo.cpp
foo.cpp: In function 'Bool something ()':
foo.cpp: 43: 22: error: could not convert '0.0' from 'double' to 'Bool'
{return TO_BOOL 0.0; } // ← Line 43
^
foo.cpp: In function 'double g ()':
foo.cpp: 48: 25: error: conversion from 'double' to non-scalar type 'Bool' requested
Bool x = TO_BOOL 0.0; // ← Line 48
^
foo.cpp: 50: 13: error: no match for 'operator =' (operand types are 'Bool' and 'double')
x = TO_BOOL f (); // where f () is a function returning a double
^
foo.cpp: 23:14: note: candidate: template <class T, class Enabled_> Bool & Bool :: operator = (T)
auto operator = (T const other)
^
foo.cpp: 23:14: note: template argument deduction / substitution failed:
foo.cpp: 12: 11: note: candidate: Bool & Bool :: operator = (const Bool &)
class bool
^
foo.cpp: 12: 11: note: no known conversion for argument 1 from 'double' to 'const Bool &'
foo.cpp: 12: 11: note: candidate: Bool & Bool :: operator = (Bool &&)
foo.cpp: 12: 11: note: no known conversion for argument 1 from 'double' to 'Bool &&'
foo.cpp: In function 'int main ()':
foo.cpp: 58: 18: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
return a && b || something ();
^
c: \ my \ forums \ so \ 105> g ++ foo.cpp -D CLEAN
foo.cpp: In function 'int main ()':
foo.cpp: 58: 18: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
return a && b || something ();
^
c: \ my \ forums \ so \ 105> g ++ foo.cpp -D CLEAN -Wno-parentheses
c: \ my \ forums \ so \ 105> _
If you want the implicit conversion from bool
to any type other than bool
to be ignored, just make sure that the conversion operator checks the template, for example, the constructor and assignment operator.