在我的职能中:
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来初始化它并没有什么区别?
答案 0 :(得分:7)
在C ++中,0.5
的类型为double
,而0.5f
的类型为float
。无法指定作为模板参数的类型的文字。在这种情况下,演员阵容是可以接受的。
我推荐static_cast
而不是功能样式。 decltype
是不必要的,相关类型已经有一个名称T
。
因此,static_cast<T>(0.5)
完全没问题。
从纯粹抽象的角度来看,有double
到float
(或任何类型T
表示的转换)。实际上,这种转换是无操作的。从编译器的角度来看,这是一个不断折叠的简单案例。
答案 1 :(得分:4)
没有转换发生?
如果T
是浮点数,那么就会发生转化。 0.5
是一个双常数。投射它是一种转换。那是纯粹的语言意义。
唯一的问题是,您没有转换为T
,而是转换为T const&
(这是decltype
给出的)。基本上,你实现了一个临时的。
按值传递将避免这种情况,并使decltype(a)
解析为T
。如果T
是float
,您将获得演员float(0.5)
。这很可能会解决为与0.5f
相同的常数。
答案 2 :(得分:0)
如果(事实上不太可能)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强制转换为{{1}}。