我有一个模板化的数学函数,它接受两个值,对它们进行一些数学运算,并返回相同类型的值。
template <typename T>
T math_function(T a, T b) {
LongT x = MATH_OP1(a,b);
return MATH_OP2(x,a);
}
我想将中间值(在x中)存储在一个基本上是T的长版本(上面称为LongT)的类型中。所以,如果T是浮点数,我希望x是双精度数;如果T是一个int,我希望x是一个long int。
有没有办法实现这个目标?我试过enable_if
,但似乎我真的需要一个enable_if_else
。
我更愿意让编译器自己弄清楚LongT的用途。当我调用函数时,我宁愿不必指定它。
答案 0 :(得分:5)
您可以定义将生成所需类型的类型映射:
template <typename T> struct long_type;
template <> struct long_type<int> {
typedef long type;
};
template <> struct long_type<float> {
typedef double type;
};
然后使用该元函数:
template <typename T>
T math_function(T a, T b) {
typename long_type<T>::type x = MATH_OP1(a,b);
return static_cast<T>(MATH_OP2(x,a));
}
使用此特定实现,您的模板将无法针对您提供long_type
特征的类型以外的任何类型进行编译。您可能希望提供仅映射到自身的通用版本,以便在输入为long long int
时使用(假设您的架构中没有更大的类型)。
答案 1 :(得分:5)
假设您不需要处理T=long
,只需为int
和float
创建特征:
template <typename T>
struct LongT;
template <>
struct LongT<int>
{
typedef long value_type;
};
template <>
struct LongT<float>
{
typedef double value_type;
};
template <typename T>
T math_function(T a, T b) {
typename LongT<T>::value_type x = MATH_OP1(a,b);
return MATH_OP2(x,a);
}
答案 2 :(得分:3)
在C ++ 11中,您可以使用auto
关键字来检索MATH_OP
的类型。它是安全的,由编译器处理。
auto x = MATH_OP1(a,b);
答案 3 :(得分:1)
template<typename T> struct LongT {typedef T type;}
template<> struct LongT<int8_t> {typedef int16_t type;}
template<> struct LongT<int16_t> {typedef int32_t type;}
template<> struct LongT<int32_t> {typedef int64_t type;}
template<> struct LongT<int64_t> {typedef intmax_t type;}
// same for unsigned ...
template<> struct LongT<float> {typedef double type;}
// template<> struct LongT<double> {typedef long double type;}
像这样使用:
typename LongT<T>::type x;
答案 4 :(得分:0)
您可以编写自己的结构专有名称,或使用类似
的内容#include <type_traits>
template<typename T>
void func(const T& f, const T& s)
{
typename std::conditional
<
std::is_same<T, float>::value,
double,
typename std::conditional
<
std::is_same<T, int>::value,
long,
void
>::type
>::type X(f + s);
(void)X;
}
int main()
{
func(1, 1);
func(1.0f, 1.0f);
func(1.0, 1.0);
}
http://liveworkspace.org/code/8f75236b880a3fe210a8751e485a47ed
但是写下你自己的专业,建议大卫或马克非常聪明。