【问题标题】:Determining in template function the shortest float type that faithfully represents integer type parameter在模板函数中确定忠实表示整数类型参数的最短浮点类型
【发布时间】:2021-06-02 19:48:05
【问题描述】:
template< typename int_type >
bool foo( int_type argument )
{
    float_type value = argument; // float_type must faithfully represent argument.
    ...
}

也就是说,我想在模板函数中导出最短的浮点类型float_type,它的有效数字至少与模板参数int_type 一样多。

foo&lt;int16&gt; 应该使用float

foo&lt;int32&gt; 应该使用double

foo&lt;int64&gt; 应该使用long double

这在没有专业化的情况下可行吗?

【问题讨论】:

  • “这在没有专业化的情况下是否可行?” - 功能模板具体...或一般?

标签: c++ c++11 templates types


【解决方案1】:

事实上,这无需直接使用专业化是可能的。您可以使用标准头 type_traits 中的 std::conditional 根据 int_type 的大小有条件地定义类型:

template< typename int_type >
bool foo(int_type argument)
{
    using float_type = std::conditional<sizeof(int_type) <= 4,
                                        std::conditional<sizeof(int_type) == 4, double, float>::type,
                                        long double>::type;
    float_type value = argument; // float_type must faithfully represent argument.
    ...
}

【讨论】:

  • 如果需要不止一次的帮助:template&lt;class int_type&gt; using faithful_float_t = std::conditional_t&lt;sizeof(int_type) &lt;= 4, std::conditional_t&lt;sizeof(int_type) == 4, double, float&gt;, long double&gt;;
  • @TedLyngmo 标签提到了 C++11。我同意你的 sn-p 很有帮助,如果你可以依赖 C++14 的特性。
  • 哎呀,我错过了 C++11 标签。 :)
【解决方案2】:

我发现虚拟函数签名是将一种类型映射到另一种类型的最简单方法。只需用输入类型重载函数,这些函数结果类型就是输出。例如

float fff (int16_t);
double fff (int32_t);

using type = decltype(fff(declval<T>()));

【讨论】:

  • 非常聪明!谢谢。
【解决方案3】:

如果您不介意查找值的专业化,您可以生成一个查找表以将整数类型显式映射到浮点类型,例如:

template <typename T>
struct IntToFloatHelper;
template <>
struct IntToFloatHelper<int16_t> {
    using type = float;
};
template <>
struct IntToFloatHelper<int32_t> {
    using type = double;
};
template <>
struct IntToFloatHelper<int64_t> {
    using type = long double;
};

// then down in the function...
typename IntToFloatHelper<int_type>::type value = argument;

如果您能够列举您想要支持的所有可能的映射,则此方法有效。如果未实现该类型,则会收到“未定义模板的隐式实例化”错误。

在我写完这篇文章后,我注意到你提到了“没有专业化”,所以也许你已经认为这是一种可行的方法,但正在寻找不同的东西。

【讨论】:

  • 我觉得我们可以将它与std::numeric_limits&lt;&gt;::digits 结合起来得出阈值(从而支持数字限制支持的所有类型)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 2020-12-20
相关资源
最近更新 更多