【问题标题】:Is there any type trait way to get int type from range capacity desired?是否有任何类型特征方法可以从所需的范围容量中获取 int 类型?
【发布时间】:2020-04-13 21:55:59
【问题描述】:

在编写一些容器类时,我很想避免使用 size_t 来进行容量和迭代,以涵盖所有情况。假设我只想要一个 50 大小的东西,一个 unsigned char 就可以了。但是我怎样才能从给定的所需容量中模板化这种类型呢?有任何类型特征吗?

template<class T, size_t capacity> MyBuffer{
 ...
 using IDX = intRequired<capacity>; // desired
 ...
 T & At(IDX at);
 IDX Lenght();

}

【问题讨论】:

  • C++ 库中没有这样的特征。但是根据numeric_limits,自己实现一个并不难。
  • 没有现有的类型特征可以满足您的要求。但是您可以自己创建一个,例如使用constexpr 语句来计算保存capacity 值(1、2、4 或 8)所需的最小字节大小,然后使用一些模板特化来选择合适的数据基于该字节大小的类型(uint8_tuint16_tuint32_tuint64_t)。
  • @walnut 我想我不明白你的意思。要访问、存储或测试容量(或大小,或使用 [] 或 At() 访问,如在 sn-p 中),用户需要一个类型
  • @RemyLebeau 它超出了我的模板能力......
  • @walnut "Capacity" /= "size",不是一般的。这可能是一个具有指定最大容量的缓冲区,但它可能在任何时候包含更少的元素。

标签: c++ templates metaprogramming typetraits


【解决方案1】:

标准中没有这样的类型特征,但您可以自己制作类似的东西:

#include <cstdint>
#include <limits>
#include <type_traits>


template <auto capacity, typename... intTypes>
struct intRequiredImpl;

template <auto capacity, typename intType>
struct intRequiredImpl<capacity, intType> {
        using type = intType;

        // avoid overflow
        static_assert(capacity <= std::numeric_limits<type>::max(), 
                "Largest specified type is not capable of holding the capacity.");
};

template <auto capacity, typename SmallInt, typename... LargeInts>
struct intRequiredImpl <capacity, SmallInt, LargeInts...>  {
        using type = std::conditional_t <
                (capacity <= std::numeric_limits<SmallInt>::max()),
                SmallInt, typename intRequiredImpl<capacity, LargeInts...>::type>;
};

template <auto capacity>
using uintRequired = typename intRequiredImpl<capacity,
                                        std::uint8_t,
                                        std::uint16_t,
                                        std::uint32_t,
                                        std::uint64_t>::type;

int main() {
        uintRequired<50> i; // std::uint8_t
}

【讨论】:

    【解决方案2】:

    得到了一些帮助,最终得到了这个:

    template<size_t Max>
        using BestFitUint = std::conditional_t < Max <= UINT8_MAX, uint8_t,
                                std::conditional_t < Max <= UINT16_MAX, uint16_t,
                                    std::conditional_t< Max <= UINT32_MAX, uint32_t,
                                        std::uint64_t > > >;
    

    工作正常,不确定与 Ayxan 的答案有何不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2015-06-18
      • 2017-08-17
      • 2021-07-22
      • 2020-05-02
      相关资源
      最近更新 更多