C++ std::is_integral 对左值和右值显示不同的结果

C++ std::is_integral on lvalue and rvalue shows different results

我创建了一个类型验证器来检查给定的参数是否为数字。

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,两个结果都为真。

这是否意味着 type_traits 的 STL 实现如 is_integralis_floating_point 等强制给定类型为右值?

如果是,为什么?

更新:

正如 geza 所述,我使用的 type_traits 库本身只指定了一个类型,这意味着

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

问题与左值或右值无关。

您似乎混淆了值类别和类型。这些有很强的联系,但又不一样。

type_traits 需要一个 type 参数。在这里讨论右值没有意义,因为 expressions 有值类别。

is_integral 需要 return true 的非引用类型。 is_integral_v<int &&>(右值引用)还是returns false,因为是引用类型。

在您的第一个示例(文字 3)中,T 将被推断为 int,因此 is_numeric_tuple 将 return true(因为它是非引用类型)。

在您的第二个示例中,T 将被推断为 int &,因此它将 return false(因为它是引用类型)。

这些类型特征旨在指示不同的类别。每种类型都属于 these categories:

之一

类型int&是引用类型,不是整数类型。因此,is_integral returns false.