c++ - 比较任意类型的整数

标签 c++ c++11

比较两个通常意外(不同)类型的两个整数的完全类型安全和最灵活(就 constexpr 而言)的方法是什么?

最佳答案

这里有一个想法:我们需要使用“通常的算术转换”:

  • 如果两种类型都是无符号的,只需比较即可。

  • 如果两种类型都已签名,则只需比较即可。

  • 如果有符号不同且有符号值为负,我们就完成了。

  • 实际工作适用于两个值都为非负且具有不同符号的情况。当无符号值大于有符号类型的最大有符号值时,我们就完成了。否则,可以将无符号值在不改变值的情况下转换为有符号类型,并进行比较。

这是一个尝试:

#include <type_traits>
#include <limits>

template <bool SameSignedness> struct IntComparerImpl;

template <typename T, typename U>
constexpr bool IntCompare(T x, U y)
{
    return IntComparerImpl<std::is_signed<T>::value ==
                           std::is_signed<U>::value>::compare(x, y);
}

// same signedness case:
template <> struct IntComparerImpl<true>
{
    template<typename T, typename U>
    static constexpr bool compare(T t, U u)
    {
        return t < u;
    } 
};

// different signedness case:
template <> struct IntComparerImpl<false>
{
    // I1 is signed, I2 is unsigned
    template <typename I1, typename I2>
    static constexpr typename std::enable_if<std::is_signed<I1>::value, bool>::type
    compare(I1 x, I2 y)
    {
        return x < 0
            || y > std::numeric_limits<I1>::max()
            || x < static_cast<I1>(y);
    }

    // I1 is unsigned, I2 is signed
    template <typename I1, typename I2>
    static typename std::enable_if<std::is_signed<I2>::value, bool>::type
    compare(I1 x, I2 y)
    {
        return !(y < 0)
            && !(x > std::numeric_limits<I2>::max())
            && static_cast<I2>(x) < y;
    }
};

关于c++ - 比较任意类型的整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16752954/

相关文章:

c++ - 在 C++ 中覆盖 new 和 delete 的通用内存分配崩溃

c++ - Qt QWebPage 运行时c++错误

c++ - 虚函数声明和定义的困惑

c++ - 使用 C++ 在同一系统上运行的两个服务之间的通信

c++ - g++ -I 不按指定顺序工作

c++ - Qt::WA_DeleteOnClose

c++ - 我应该拒绝 C++,因为它正在成为一个主宰吗?

c++ - 使用 PostgreSQL 连接器安装 SQLpp11

c++ - 如何使用 enable_if 来限制整个类(class)

c++ - 在链接阶段诊断 "contains undefined reference for architecture"