简体   繁体   中英

how to use the type of compile time constant primitive

How to use the type of a compile time constant primitive as type declaration for other variables?

I am trying to do some template metaprogramming in c++ for SI unit conversion. It comes down to how to automatically determine which primitive precision I need after one plus operator. For example:

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;
}

or in simple terms, can some thing like this happen?

float a = 1;
typeof(a) b = 2;

It seems quite possible since I've gone this far. But I am not sure how to use

You almost got it. As max66 already pointed out, use decltype . First of all, you can replace your PrecisionTransform class with the follwing type alias (you have to #include <utility> for this):

template <typename Precision1, typename Precision2>
using TransformType = decltype(std::declval<Precision1>() * std::declval<Precision2>());

The std::declval<XYZ>() is just a more generic way of saying (Precision1)1 which allows you to also use types that don't have accessible constructors (in your case irrelevant as you only use primitives).

Your operator+ is then changed to:

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);
}

Note that you got a typo in your version of operator+ (both operands used Precision1 ).

As you can see here , the major compilers agree on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM