问题描述
template< typename int_type >
bool foo( int_type argument )
{
float_type value = argument; // float_type must faithfully represent argument.
...
}
也就是说,我想在模板函数中导出最短的浮点类型 float_type
,它的有效数字至少与模板参数 int_type
一样多。
foo<int16>
应该使用 float
。
foo<int32>
应该使用 double
。
foo<int64>
应该使用 long double
。
这在没有专业化的情况下可行吗?
解决方法
确实可以在不直接使用专业化的情况下做到这一点。您可以使用标准标头 std::conditional
中的 type_traits
根据 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.
...
}
,
我发现虚拟函数签名是将一种类型映射到另一种类型的最简单方法。只需使用输入类型重载函数,这些函数结果类型就是输出。例如
float fff (int16_t);
double fff (int32_t);
using type = decltype(fff(declval<T>()));
,
如果您不介意查找值的专业化,您可以生成一个查找表以将整数类型显式映射到浮点类型,例如:
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;
如果您能够枚举您想要支持的所有可能的映射,则此方法有效。如果未实现该类型,则会出现“未定义模板的隐式实例化”错误。
在我写这篇文章之后,我注意到你提到了“没有专业化”,所以也许你已经认为这是一种可能的方法,但正在寻找不同的东西。