I'm trying to make it simple to check at compile time whether the conversion of one value to a new type preserves the value. There may be something in the STL that can do this for me, but I don't see it, so I wrote one. It works, but I wanted to convert it to a class in order to make the use a little simpler for others. I can't get that to work and I feel like I'm missing something obvious.
This works fine:
template <typename T, typename Q>
constexpr bool checkV(const Q x)
{return x == (T)x && ((x < 0) == ((T)x < 0));}
static_assert(checkV<unsigned int>(-7), "No");
But the call is ungainly, so I wanted something more like
CheckIt<unsigned int>(-7)
and so I attempted
template<typename T>
class CheckIt {public:
template<typename Q>
constexpr CheckIt(const Q x) {static_assert(checkV<T>(x), "No");}
};
I've tried various combinations of const and constexpr (and discovered parameters can't be constexprs, which is annoying). Everything I try results in g++ complaining that x is not a constant expression in the constructor.
What am I missing? checkv, and the constructor, are both always called with constants, like -7. checkv() is happy to evaluate at compile time and I can't see where using a constructor function to wrap that adds any additional burden to the compiler, but obviously it does. Note I need this to work in C++11, but I don't see where later versions will help. I have no problems checking at runtime, with assert, but I want the compile time solution for constants. TIA.
xhas to be a template parameter.static_assert(checkV<unsigned int>(-7), "No");would be the only option for c++11I want the compile time solution for constants- so you want to detect if the parameter is a constant, and then usestatic_assert? If it should be only constant, use templates.checkVall of the parentheses except for those in the two casts are redundant.xas a function parameter would never work, as it's a variable, not a constand expression.