加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 确定临时模板的大小

发布时间:2020-12-16 07:15:26 所属栏目:百科 来源:网络整理
导读:我有一个模板类,需要能够在一个类型的两个实例之间进行插值.所以我的类调用一个名为interpolate的用户提供的函数,具有以下签名: templatetypename TT interpolate(uint32_t distance,const T from,const T to); 这里,距离从0到0xFFFF. 现在,我想为常见类型
我有一个模板类,需要能够在一个类型的两个实例之间进行插值.所以我的类调用一个名为interpolate的用户提供的函数,具有以下签名:

template<typename T>
T interpolate(uint32_t distance,const T& from,const T& to);

这里,距离从0到0xFFFF.

现在,我想为常见类型的T提供理智的实现,例如uint32_t.所以我编写了一个示例实现(忽略它仅针对签名类型实现):

template<typename T>
inline auto interpolate(uint32_t distance,const T& to)
    -> std::enable_if_t<std::is_signed<T>::value,T>
{
    return from + ((distance * (to - from)) / 0xFFFF);
}

这适用于小于32位的类型,因为距离永远不会大于16位,而距离*(来自 – )的结果是uint32_t.但是32位不足以包含0xFFFF * uint32_t的结果 – 在这种情况下,模板需要64位临时值.

有没有一种标准化的方法我可以选择比“T更大”的类型来保存临时结果?显然,这只需要适用于内在类型;用户的类型仍然需要自己的插值实现.

解决方法

首先,正如您所说,您的插值因子只能从0到0xFFFF.您应该有一个反映该类型以最小化潜在错误的类型 – 即不要使用uint32_t而是使用uint16_t.根据经验,你应该避免在参数中花费超过你需要的量.所以一般的签名是:

template<typename T>
T interpolate(uint16_t factor,const T& to);

请注意,在进行插值时,结果可能会超出[from;因此,界面中不需要更大的类型.

现在,你通过整数插值使你的生活变得复杂.我不知道为什么你不想要浮点插值(特别是对于动画框架,我们不再是1995年了!).

所以,如果你真的想要整数风格,那么你需要一个更大的整数来保持它.你能做的最简单:

template<typename I> struct bigger_integer;
template<> struct bigger_integer<int8_t>   { typedef int16_t type; };
template<> struct bigger_integer<int16_t>  { typedef int32_t type; };
template<> struct bigger_integer<int32_t>  { typedef int64_t type; };
template<> struct bigger_integer<uint8_t>  { typedef uint16_t type; };
template<> struct bigger_integer<uint16_t> { typedef uint32_t type; };
template<> struct bigger_integer<uint32_t> { typedef uint64_t type; };

并且,在您的函数中,使用以下更大的类型:

using I = std::make_signed_t<typename bigger_integer<T>::type>;

它甚至适用于经过微小修改的无符号类型.

我的意见:使用双打.如果在分析会话后发现它们导致性能问题,那么您可以尝试优化它们.但老实说我怀疑情况会是这样.这里的代码更简单:

template<typename T>
T interpolate(uint16_t factor,const T& to)
{
    return T(double(from) + double(factor) * (double(to) - double(from)) / double(0xFFFF));
}

Live example here.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读