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

标签 c++ templates casting warnings

设置

我正在使用名为 MotionBuilder 的应用程序的 API。为了访问 MotionBuilder 属性的值,您可以将其读入 double 变量,而不管它实际表示哪种数据类型。

这是我编写的用于评估标量属性值的效用函数:

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)而不是让我的代码乱七八糟的多行未初始化缓冲区和强制转换。

我在 Visual Studio 中使用 /W4 进行编译并解决所有出现的警告。当我使用 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

我可以直接用 pragmas 抑制警告,因为 Actor 正在做我想要它做的事情:

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 .事实上,在 Release模式下编译的一个简单测试在两种情况下都为我提供了相同的汇编输出。那么,为什么 C4800 称自己为“性能警告”?上面列出的两个选项在功能上是否相同?如果归结为风格问题,在戴上你最好的学究帽之后,你更喜欢哪个选项?

最佳答案

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

关于c++ - `static_cast<bool>(x)` 和 `x != 0.0` 之间有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17580890/

相关文章:

python - 将原始数字写入磁盘

c++ - 在没有 delete 运算符的情况下编译 C++

c++ - SFML2 与 mingw32 : undefined references 的静态链接错误

c# - 无法将 Exam_Mapper 的类型转换为 IMapper 的类型

c++ - 是否可以获取传递给模板的函数的名称?

c++ - 模板类内部类的映射迭代器的正确语法?

c++ - 将不同大小的 C 数组传递给采用 2 个相同参数的模板函数

c++ - 如何使用 get std::bind 之类的行为

java - 将父类扭曲为子类

c# - 由于某种原因,字节乘以字节是 int。为什么?无法将类型 'int' 隐式转换为 'byte' 。存在显式转换