`static_cast<bool>(x)` 和 `x != 0.0` 之间有区别吗?

awf*_*the 5 c++ templates warnings casting

设置

我正在使用名为 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);
}
Run Code Online (Sandbox Code Playgroud)

这样,我可以编写GetScalar<float>(camera.Roll, evaluateInfo)orGetScalar<bool>(camera.Visibility, evaluateInfo)来代替多行乱七八糟的未初始化缓冲区和强制转换乱七八糟的代码。

我正在 Visual Studio 中进行编译/W4并解决出现的所有警告。当我使用时GetScalar<bool>,编译器会产生C4800 警告

'double' : forcing value to bool 'true' or 'false' (performance warning)
Run Code Online (Sandbox Code Playgroud)

当编译器创建 时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)
}
Run Code Online (Sandbox Code Playgroud)

选项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;
}
Run Code Online (Sandbox Code Playgroud)

问题

我认为对于某些 double x,static_cast<bool>(x)完全等同于x != 0.0. 事实上,在发布模式下编译的简单测试在两种情况下都为我提供了相同的程序集输出。那么,为什么 C4800 称自己为“性能警告”呢?上述两个选项的功能是否相同?如果归根结底是风格问题,戴上你最好的学究帽后,你更喜欢哪种选择?

Pet*_*ker 4

这是一条警告,告诉您此转换可能存在性能问题。既然你想做转换,那就做吧。不要浪费时间为没有告诉您任何有用信息的警告编写复杂的解决方法。