Suppose I have some templated code which does the following:
T x = foo();
T y = -x;
Now, if T is a non-numeric type (or which doesn't have the unary minus implemented), the compilation will simply fail. But if it's an unsigned int, unsigned short etc., it will succeed, with a warning. So I would like to be able to do
T x = foo();
if (/* magic condition */ {
T y = -x;
}
Can I write express the condition - which is checked either at compile time or at run time - of T's type being some signed numeric type? e.g. using typeid?
Note:
C++11 has the is_unsigned
trait, which you can use in a static_assert
:
#include <type_traits>
template <typename T>
void foo()
{
static_assert(std::is_unsigned<T>::value);
T x = /* ... */
T y = -x;
/* ... */
}
If you need the check to be more dynamic, then just stick it in an if
condition:
template <typename T>
void foo()
{
if (!std::is_unsigned<T>::value) {
/* To arrive here and for the following
not to error out, we must have a numeric
type that's not unsigned! */
T x = /* ... */
T y = -x;
}
else {
/* Do something else for unsigned numeric
types */
}
}
More complex solutions involve overloads, std::enable_if
and all sorts of other template metahackery, but the above may be all you need.
Yes you can.
static_assert(std::is_unsigned<T>::value, "Not unsigned!");
(You need to include type_traits for this to work.)
You can then naturally adjust your compilation process, potentially even with enable_if
if you're sure there is no other way :).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With