boolean_cast






4.39/5 (13投票s)
2005年12月4日
2分钟阅读

48591

214
执行 bool、BOOL 和 VARIANT_BOOL 类型的值之间的转换。
动机
我们不能忽略编译器警告,但它们有时很烦人
void motivation(HWND hWnd) { bool b = ::IsWindow(hWnd); // warning C4800 }
上面的代码会产生警告
warning C4800: 'BOOL' : forcing value to bool 'true'
or 'false' (performance warning)
static_cast
会产生与上面给出的警告相同的警告。 然后你写
void wrong(HWND hWnd) { bool b = (::IsWindow(hWnd) == TRUE); }
行为是未定义的,因为 Win32 文档说
If the window handle identifies an existing window,
the return value is nonzero.
If the window handle does not identify an existing window,
the return value is zero.
您可能认为 BOOL
定义为 TRUE
或 FALSE
,但似乎是错误的。 然后你写
void right(HWND hWnd) { bool b = (::IsWindow(hWnd) != 0); }
您的工作已完成(您可以将 FALSE
写为 0)。 无论如何,您一定认为它仍然很烦人。 这就是 boolean_cast
的用武之地。
要求
- Microsoft Visual C++ .NET 7.1 版
- BooleanCast 的最新版本
boolean_cast
在命名空间 poost
中定义的 boolean_cast
安全地转换 bool
、BOOL
和 VARIANT_BOOL
类型之间的值
void good(HWND hWnd) { bool b = boolean_cast<bool>(::IsWindow(hWnd)); }
VARIANT_TRUE
定义为 ((short)-1
),实际上,隐式转换是危险的
void good_save() { VARIANT_BOOL vb = TRUE; ATLASSERT( vb != VARIANT_TRUE ); // wow! vb = boolean_cast<VARIANT_BOOL>(TRUE); ATLASSERT( vb == VARIANT_TRUE ); }
boolean_cast
提高了安全性和可读性。 但是,为什么要编写目标类型? 编译器必须知道类型。
auto_boolean
auto_boolean
使用已分配对象的类型作为目标类型
void best(HWND hWnd) { bool b = auto_boolean(::IsWindow(hWnd)); }
这就是你想要的。 没有警告,没有烦恼。 请注意,auto_boolean
在像 VC6 或 eVC4 这样的损坏的编译器下不起作用。
工作原理
boolean_cast
的实现如下
template< class TargetT, class SourceT > TargetT boolean_cast(SourceT b) { typedef boolean_converter<TargetT, SourceT> converter_t; return converter_t::convert(b); }
boolean_cast
将其任务委托给 boolean_converter
类模板。 真正的任务由模板执行。 让我们看一下实现
// primary template template< class TargetT, class SourceT > struct boolean_converter; // full specialization template< > struct boolean_converter<bool, BOOL> { static bool convert(BOOL b) { return b ? true : false; } }
该任务被发送到“完全类模板特化”,具体取决于两种类型:TargetT
和 SourceT
。
接下来,让我们看看 auto_boolean
。 这有点技术性
template< class SourceT > struct auto_boolean_type { explicit auto_boolean_type(SourceT b) : m_b(b) { } // conversion operator template< class TargetT > operator TargetT() const { return boolean_cast<TargetT>(m_b); } private: SourceT m_b; }; template< class SourceT > auto_boolean_type<SourceT> auto_boolean(SourceT b) { return auto_boolean_type<SourceT>(b); }
有趣的是,auto_boolean
返回的不是类型,而是 auto_boolean_type
。 编译器必须将 auto_boolean_type
转换为目标类型。 他们找到并调用“转换运算符”,最后自动调用 boolean_cast
,而不是你调用它。
关注点
reinterpret_cast
和 static_cast
在大多数程序中都得到大量使用。 如果您几个月没有查看您的代码,确定每个强制转换都在做什么可能很耗时,并且像 boolean_cast
这样的特定于域的强制转换可以帮助您减少此时间。
在以下情况下测试
- Microsoft Visual C++ .NET 7.1 版
- Embedded Visual C++ 4.0 SP4
- Test Drive Comeau C++ Online(仅解析)
参考文献
历史
- 2005 年 12 月 5 日:上传了初始版本。
- 2005 年 12 月 6 日:文档已更新。