这是为浮点数/双精度函数泛型的正确方法吗?
Is this the correct way to genericise a function for floats/doubles
在我的函数中:
template <typename T>
T lerpMidway(const T& a, const T& b)
{
T result;
result = (b - a) * 0.5 + a;
return result;
}
int main()
{
lerpMidway(4.f, 6.f);
}
如果我将浮点值传递给这个函数,我认为 0.5 会将所有其他浮点数提升为双精度,然后在需要返回它时将其转换回浮点数。
我试了这行:
result = (b - a) * decltype(a)(0.5) + a;
它摆脱了编译器消息说双精度以浮点可能丢失数据,但在这里,如果"a"是浮点数,并且我用双精度初始化它,则不会发生转换吗?我也可以用 0.5f 初始化它,它不会有什么区别吗?
在C++中,0.5
的类型为 double
,0.5f
的类型为 float
。无法指定作为模板参数的类型的文本。在这种情况下,石膏是可以接受的。
我推荐static_cast
而不是功能性风格的演员表。 decltype
是不必要的,则相关类型已经有一个名称,T
。
因此,static_cast<T>(0.5)
完全没问题。
从纯粹抽象的角度来看,有一个从double
到float
(或T
表示的任何类型的(的转换。实际上,这种转换是无操作的。从编译器的角度来看,这是一个持续折叠的简单情况。
没有发生转换?
如果T
是浮点数,则会发生转换。 0.5
是一个双重常数。铸造它是一种转换。这是从纯粹的语言意义上说的。
唯一的问题是,你不是转换为T
,而是转换为T const&
(这就是decltype
给出的(。从本质上讲,你实现了暂时的。
按值传递将避免这种情况,并使decltype(a)
决心T
。如果T
是float
,您将获得演员float(0.5)
。这很可能会解析为与0.5f
相同的常数。
以防万一(诚然不太可能(T 是易失性浮点数的情况,我可能倾向于将函数写成这样:
#include <type_traits>
template <typename T>
auto lerpMidway(const T& a, const T& b) -> std::decay_t<T>
{
using type = std::decay_t<T>;
const auto factor = type(0.5);
type result;
result = (b - a) * factor + a;
return result;
}
因为decltype(a)
会const volatile float&
,你不能把double
0.5 投射到那个。
相关文章:
- 传递非泛型函数的最有效方法是什么?
- 对列表类中的泛型方法禁用编译器警告 2100,该泛型方法可能包含指针,也可能不包含指针
- 泛型方法指针.reinterpret_cast指向不同类的方法指针,这是 UB 吗?
- 如何将泛型方法传递给静态函数
- 使用泛型成员变量"placement new"结构/类数组的正确方法是什么?
- 这是为浮点数/双精度函数泛型的正确方法吗?
- 基于变量输入的泛型类方法计算
- 有没有一种方法可以在c++中比较泛型类型(模板)和具体类型
- 推导函子返回类型的泛型方法
- 对给定结构成员应用操作的泛型方法
- 如何在参数为泛型类型的模板类中为方法类型化定义函数签名
- 使用基类的泛型方法指针调用派生类的方法
- 用返回子类的方法设计C++泛型类
- C++返回类型的泛型集合的正确方法
- 具有泛型类方法定义的长模板参数列表
- c++中的泛型方法
- 从方法指针动态创建泛型函数指针,推导返回值和参数
- 在Swift中定义显式泛型方法
- 如何强制.net (c#)使用方法的非泛型重载?
- c++:在泛型代码中获取对象大小的最佳方法