检查数字类型是否为另一个的子集

时间:2019-08-31 22:07:45

标签: c++ templates predicate numeric-limits

我尝试实现一个meta函数,该函数检查一个整数类型是否是另一个整数类型的子集。它应该独立于平台,并且至少与C ++标准定义的所有数字类型一起使用。我当前的实现有5个分支。我有两个问题。

  1. 我想念任何案件吗?
  2. 第四分支是否必要?
template <typename T1, typename T2>
constexpr bool is_subset(T1, T2)
{
    if constexpr (std::is_same_v<T1, T2>)
    {
        return true;
    }
    if constexpr (std::is_same_v<T1, std::uintmax_t>)
    {
        return false;
    }
    else if constexpr (std::is_same_v<T1, std::intmax_t>)
    {
        return false;
    }
    else if constexpr (std::is_unsigned_v<T1> && std::is_unsigned_v<T2>)
    {
        return static_cast<std::uintmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::uintmax_t>(std::numeric_limits<T2>::min()) &&
               static_cast<std::uintmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::uintmax_t>(std::numeric_limits<T2>::max())
    }
    else
    {
        return static_cast<std::intmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::intmax_t>(std::numeric_limits<T2>::min()) &&
               static_cast<std::intmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::intmax_t>(std::numeric_limits<T2>::max())
    }
}

固定的intmax_t == long实现:

template <typename T1, typename T2>
constexpr bool is_subset2(T1, T2) noexcept
{
    if constexpr (sizeof(T1) == sizeof(T2) && std::is_signed_v<T1> == std::is_signed_v<T2>)
    {
        return true;
    }      
    else if constexpr (sizeof(T1) == sizeof(std::intmax_t))
    {
        return false;
    }   
    else if constexpr (std::is_unsigned_v<T1> && std::is_unsigned_v<T2>)
    {
        return static_cast<std::uintmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::uintmax_t>(std::numeric_limits<T2>::min()) &&
               static_cast<std::uintmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::uintmax_t>(std::numeric_limits<T2>::max());
    }
    else
    {
        return static_cast<std::intmax_t>(std::numeric_limits<T1>::min()) >= static_cast<std::intmax_t>(std::numeric_limits<T2>::min()) &&
               static_cast<std::intmax_t>(std::numeric_limits<T1>::max()) <= static_cast<std::intmax_t>(std::numeric_limits<T2>::max());
    }
}

1 个答案:

答案 0 :(得分:1)

我不知道为什么您有std::uintmax_tstd::intmax_t的单独案例。我认为可以将其简化为3种情况:

template <typename T1, typename T2>
constexpr bool is_subset2(T1, T2) noexcept
{
    if constexpr (sizeof(T1) == sizeof(T2))
    {
        // true if both signed or both unsigned
        return std::is_signed_v<T1> == std::is_signed_v<T2>;
    }
    else if constexpr (sizeof(T1) < sizeof(T2))
    {
        // true if both unsigned, or T2 is signed
        return std::is_signed_v<T2> || (std::is_unsigned_v<T1> && std::is_unsigned_v<T2>);
    }
    else
    {
        return false;
    }
}