如何使用编译时常量原语的类型作为其他变量的类型声明?
我正在尝试使用c ++进行一些模板元编程以实现SI单位转换。归结为如何在一个加号运算符之后自动确定我需要的原始精度。例如:
template<typename Precision>
class Unit {
public:
Unit(Precision v) : value(v) {}
Precision value;
};
template<typename Precision1, typename Precision2>
struct PrecisionTransform {
constexpr static auto test = (Precision1)1 * (Precision2)1; // Compile time constant
using Type = Precision1; // TODO: ideally typeof(test)
};
template<typename Precision1, typename Precision2>
Unit<PrecisionTransform<Precision1, Precision2>::Type> operator+(const Unit<Precision1>& x, const Unit<Precision2>& y)
{
return Unit<PrecisionTransform<Precision1, Precision2>::Type>(x.value + y.value);
}
int main()
{
Unit<double> a = 2.0;
Unit<float> b = 1.0f;
auto c = a + b;
return 0;
}
或者简单地说,这样的事情会发生吗?
float a = 1;
typeof(a) b = 2;
自从我走了这么远以来,这似乎很有可能。但是我不确定如何使用
答案 0 :(得分:2)
您几乎明白了。正如max66已经指出的那样,请使用decltype
。首先,您可以将PrecisionTransform
类替换为以下类型的别名(为此必须使用#include <utility>
)
template <typename Precision1, typename Precision2>
using TransformType = decltype(std::declval<Precision1>() * std::declval<Precision2>());
std::declval<XYZ>()
只是(Precision1)1
的更通用的表达方式,它使您还可以使用没有可访问的构造函数的类型(在您的情况下就不相关,因为您仅使用基元)。
您的operator+
然后更改为:
template<typename Precision1, typename Precision2>
Unit<TransformType<Precision1, Precision2>> operator+(const Unit<Precision1>& x, const Unit<Precision2>& y)
{
return Unit<TransformType<Precision1, Precision2>>(x.value + y.value);
}
请注意,您使用的operator+
版本中有一个错字(两个操作数都使用Precision1
)。
您可以看到here,主要的编译器对此表示同意。