Есть ли какой-либо типовой способ получить тип int из требуемого диапазона? - PullRequest
0 голосов
/ 14 апреля 2020

При написании некоторых контейнерных классов я чувствую необходимость избегать использования size_t для емкости и итерации, чтобы охватить каждый случай. Скажем, я хочу всего 50 штук, подойдет неподписанный символ .. Но как я могу шаблонировать этот тип с заданной требуемой емкостью? Есть ли какая-нибудь черта характера для этого?

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

}

Ответы [ 2 ]

3 голосов
/ 14 апреля 2020

Нет такой черты типа в стандарте, но вы можете сделать что-то похожее самостоятельно:

#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
}
0 голосов
/ 14 апреля 2020

Получил некоторую помощь и закончил с этим:

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.

...