【发布时间】:2013-07-10 21:06:57
【问题描述】:
设置
我正在为一个名为 MotionBuilder 的应用程序使用 API。为了访问 MotionBuilder 属性的值,您将其读入一个双精度变量,而不管它实际代表的是哪种数据类型。
这是我编写的一个实用函数,用于评估标量属性的值:
template <typename DataT>
inline DataT GetScalar(FBProperty& prop, FBEvaluateInfo* evaluateInfo)
{
double data = 0.0;
prop.GetData(&data, sizeof(data), evaluateInfo);
return static_cast<DataT>(data);
}
这样,我可以编写GetScalar<float>(camera.Roll, evaluateInfo) 或GetScalar<bool>(camera.Visibility, evaluateInfo),而不是让未初始化的缓冲区和强制转换乱七八糟的多行乱七八糟的代码。
我正在使用 /W4 在 Visual Studio 中进行编译,并在出现所有警告时对其进行处理。当我使用GetScalar<bool> 时,编译器会生成a C4800 warning:
'double' : forcing value to bool 'true' or 'false' (performance warning)
当编译器创建GetScalar<bool> 时,它会以一个从double 到bool 的static_cast 结束,这显然是它不喜欢的。由于我最初的目标是使用单个模板函数处理多种类型(bool、float、double 等),因此我不能只添加通常的 != 0.0。
为了解决这个警告,我有两个选择。
选项 1
我可以直接使用编译指示来抑制警告,因为演员正在做我想让它做的事情:
template <typename DataT>
inline DataT GetScalar(FBProperty& prop, FBEvaluateInfo* evaluateInfo)
{
double data = 0.0;
prop.GetData(&data, sizeof(data), evaluateInfo);
#pragma warning (push)
#pragma warning (disable: 4800) // Don't complain about casting to bool
return static_cast<DataT>(data);
#pragma warning (pop)
}
选项 2
我可以添加GetScalar 的特化来处理bool 案例:
template <>
inline bool GetScalar<bool>(FBProperty& prop, FBEvaluateInfo* evaluateInfo)
{
double data = 0.0;
prop.GetData(&data, sizeof(data), evaluateInfo);
return data != 0.0;
}
问题
我认为对于某些双 x,static_cast<bool>(x) 完全等同于 x != 0.0。事实上,在发布模式下编译的简单测试在两种情况下都会给我相同的程序集输出。那么,为什么 C4800 会称自己为“性能警告”呢?上面列出的两个选项在功能上是否相同?如果归结为风格问题,戴上你最好的学究式帽子后,你更喜欢哪个选项?
【问题讨论】:
-
另一个选项是
!!x,它返回bool。
标签: c++ templates casting warnings