Visual C++编译器会警告转换为
bool
,但是带有愚蠢的
性能警告。通常这是不需要的警告,但不幸的是它不能通过简单的强制转换来消除。几乎惯用语法来消除它是使用双重否定,
!!
,bang-bang,例如
return !!0.0
。
你的问题相反,你希望出现这样的警告或错误,但仍然可以使用bang-bang几乎惯用语法的一部分来解决问题。
通过以下示例所示的思路,您只需在需要布尔值的位置写入
Bool
,并使用
!!
确保清晰的
bool
值,否则您将得到编译错误。
这个好处是您很可能只需全局搜索和替换代码,将
bool
替换为
Bool
。
#ifdef CLEAN
# define TO_BOOL !!
#else
# define TO_BOOL
#endif
#define STATIC_ASSERT( e ) static_assert( e, #e )
#include <type_traits>
#include <utility>
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; }
auto g()
-> double
{
Bool x = TO_BOOL 0.0;
if (something()) {
x = TO_BOOL f();
}
return x;
}
auto main() -> int
{
Bool a, b, c;
return a && b || something();
}
使用g++编译的示例:
c:\my\forums\so\105> g++ foo.cpp
foo.cpp: 在函数 'Bool something()' 中:
foo.cpp:43:22: 错误:无法将'0.0'从'double'转换为'Bool'
{ return TO_BOOL 0.0; } // ← Line 43
^
foo.cpp: 在函数 'double g()' 中:
foo.cpp:48:25: 错误:请求将'double'转换为非标量类型'Bool'
Bool x = TO_BOOL 0.0; // ← Line 48
^
foo.cpp:50:13: 错误:没有匹配的运算符'='(操作数类型是'Bool'和'double')
x = TO_BOOL f(); // where f() is a function returning a double
^
foo.cpp:23:14: 注:候选函数模板<class T, class Enabled_> Bool& Bool::operator=(T)
auto operator=( T const other )
^
foo.cpp:23:14: 注: 模板参数推断/替换失败:
foo.cpp:12:11: 注:候选:Bool& Bool::operator=(const Bool&)
class Bool
^
foo.cpp:12:11: 注: 没有将第1个参数从'double'转换为'const Bool&'
foo.cpp:12:11: 注:候选:Bool& Bool::operator=(Bool&&)
foo.cpp:12:11: 注: 没有将第1个参数从'double'转换为'Bool&&'
foo.cpp: 在函数 'int main()' 中:
foo.cpp:58:18: 警告:建议在'||'内加上'&&'的括号 [-Wparentheses]
return a && b || something();
^
c:\my\forums\so\105> g++ foo.cpp -D CLEAN
foo.cpp: 在函数 'int main()' 中:
foo.cpp:58:18: 警告:建议在'||'内加上'&&'的括号 [-Wparentheses]
return a && b || something();
^
c:\my\forums\so\105> g++ foo.cpp -D CLEAN -Wno-parentheses
c:\my\forums\so\105> _
如果您希望将Bool
隐式转换为除bool
以外的其他类型不被考虑,则还需将该转换运算符作为已检查的模板进行转换,就像构造函数和赋值运算符一样。
-pedantic-errors
吗? - Violet Giraffe