4

I created a type validator to check whether a given argument is numeric.

template<typename T>
struct is_numeric
    : std::integral_constant<
        bool,
        std::is_integral_v<T> || std::is_floating_point_v<T>
    > {};

template<typename T>
inline constexpr bool is_numeric_v = is_numeric<T>::value;

template<typename T>
constexpr bool is_numeric_tuple(T&& value)
{ return is_numeric_v<T>; }

// variadic template implementation is omitted

Now, the problem is that

int i = 3;
is_numeric_tuple(3)  // returns true
is_numeric_tuple(i)  // returns false

And if I apply std::remove_reference to is_numeric_tuple, both results turn out to be true.

Does it mean that the STL implementation of type_traits like is_integral, is_floating_point, etc enforces given type to be rvalue?

And if so, why?

UPDATE:

As noted by geza, type_traits library I used only specifies a type itself, which means that

std::is_integral_v<int>;    // returns true
std::is_integral_v<int&>;   // returns false
std::is_integral_v<int&&>;  // returns false

The issue is not about either lvalue or rvalue.

PHD
  • 595
  • 1
  • 8
  • 18

2 Answers2

1

It seems that you're mixing up value category and types. These are strongly connected, but not the same.

type_traits needs a type parameter. It doesn't make sense to talk about rvalues here, as expressions has value category.

is_integral needs a non-reference type to return true. is_integral_v<int &&> (rvalue reference) still returns false, because it is a reference type.

In your first example (the literal 3), T will be deduced as int, so is is_numeric_tuple will return true (as it is a non reference type).

In your second example, T will be deduced as int &, so it will return false (as it is a reference type).

geza
  • 28,403
  • 6
  • 61
  • 135
0

These type traits are meant to indicate different categories. Every type falls under one of these categories:

enter image description here

The type int& is a reference type, not an integral type. Therefore, is_integral returns false.

L. F.
  • 19,445
  • 8
  • 48
  • 82