C ++ std :: is_integral для lvalue и rvalue показывает разные результаты - PullRequest
4 голосов
/ 25 апреля 2020

Я создал валидатор типа, чтобы проверить, является ли данный аргумент цифрой c.

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

Теперь проблема в том, что

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

И если я применяю std::remove_reference до is_numeric_tuple, оба результата оказываются верными.

Означает ли это, что реализация STL type_traits подобно is_integral, is_floating_point, et c заставляет данный тип быть значением rvalue ?

И если да, то почему?

ОБНОВЛЕНИЕ :

Как отмечено в библиотеке gaza , type_traits, которую я использовал указывает только сам тип, что означает, что

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

Проблема не в lvalue или rvalue.

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Кажется, вы смешиваете категорию и типы значений. Они сильно связаны, но не одинаковы.

type_traits требуется параметр type . Здесь не имеет смысла говорить о rvalues, поскольку выражений имеет категорию значений.

is_integral для возврата true требуется не ссылочный тип. is_integral_v<int &&> (rvalue reference) все еще возвращает false, потому что это ссылочный тип.

В вашем первом примере (литерал 3), T будет выведен как int, поэтому is is_numeric_tuple вернет true (поскольку это не ссылочный тип).

Во втором примере T будет выведено как int &, поэтому будет возвращено false (как это ссылочный тип).

0 голосов
/ 25 апреля 2020

Эти типовые черты предназначены для обозначения разных категорий. Каждый тип подпадает под одну из этих категорий :

enter image description here

Тип int& является ссылочным типом, а не целым типом , Следовательно, is_integral возвращает false.

...