【问题标题】:Filter typenames in C++在 C++ 中过滤类型名
【发布时间】:2023-03-29 12:21:01
【问题描述】:

这是我的字节数组(向量)转换器。

template<typename T>
void put(T value) {
    int size = sizeof(value);

    uint8_t *array;
    array = reinterpret_cast<uint8_t *>(&value);

    if (littleEndian) {
        for (int i = 0; i < size; i++) {
            arr.push_back(array[i]);
        }
    } else {
        for (int i = size - 1; i >= 0; i--) {
            arr.push_back(array[i]);
        }
    }
}

如您所见,此函数接受所有变量类型。是否可以过滤类型名?例如。我只想允许uint8_t, int8_t, uint16_t, int16_t etc. + float and double too?我不想发表 10 条 if 声明,因为它看起来不干净。

【问题讨论】:

  • 在不同的语句中声明和赋值给array有什么意义?

标签: c++ templates reinterpret-cast typename


【解决方案1】:

您可以使用std::is_integral 和 SFINAE 执行此操作。如果类型不是整数类型,这将从考虑中删除模板。它看起来像

template<typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
void put(T value)
{
    // code
}

Live Example

如果您希望允许所有整数和浮点类型,那么您可以使用 std::is_arithmetic like

template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
void put(T value)
{
    // code
}

【讨论】:

  • 可以加float和double吗?
  • @SzymonMarczak 如果你想要整数和浮点类型,那么你想使用std::is_arithmetic
  • 非常感谢 :)
【解决方案2】:

看来您需要一个只接受任何整数类型的函数。

&lt;type_traits&gt; 标头有一个现有的类型特征,称为 std::is_integral。您可以将它与std::enable_if 一起使用以产生预期的约束:

template<typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
void put(T value) {
    constexpr int size = sizeof(value);

    uint8_t *array;
    array = reinterpret_cast<uint8_t *>(&value);

    if (littleEndian) {
        for (int i = 0; i < size; i++) {
            arr.push_back(array[i]);
        }
    } else {
        for (int i = size - 1; i >= 0; i--) {
            arr.push_back(array[i]);
        }
    }
}

您的函数现在不能使用非整数类型调用。

请注意,如果函数有另一个重载,编译器也会尝试。这意味着,如果您有另一个接受任何浮点类型的函数,编译器将选择适当的重载。

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    相关资源
    最近更新 更多