9

コンパイル時に、特定の数値を表すことができる最小の符号なし整数型を把握する必要があります。このようなもの...

//////////////////////////////////////////////////////////////////////////
template<size_t Bits>
struct uint_least{};

template<>
struct uint_least<8>{ typedef std::uint8_t type; };

template<>
struct uint_least<16>{ typedef std::uint16_t type; };

//////////////////////////////////////////////////////////////////////////
template<size_t max>
struct uint_least_bits
{
    static const size_t value = 14; // just a placeholder
};

//////////////////////////////////////////////////////////////////////////
template<size_t max>
class A
{
    typedef typename uint_least<uint_least_bits<max>::value>::type underlying_type;

    underlying_type m_X;
};

uint_leastは、少なくともBits大きい最小の符号なし整数型を提供することを目的としており、64までの任意の値(8、16、32、64だけでなく、1、4、13など)でも機能するはずです。

uint_least_bitsを表すために必要な最小ビット数を提供することを目的としていますmax

  • どうすれば実装できuint_leastますか?
  • どうすれば実装できuint_least_bitsますか?
  • 、、およびはどのタイプにする必要bitsがありますか?答えがテンプレートタイプの場合、無効な入力を防ぐにはどうすればよいですか?minmax

特性の正確な構造は重要ではありません。私が提供したものを自由に廃棄してください。数値を入力して、それを保持できる最小の符号なし整数型を取得する必要があります。

4

2 に答える 2

9

私は昨日これをしました、なんて偶然です。それはあなたが必要としているものではありませんが、ここに残しておきます(とにかく最高の積分型のものを修正します):

#include <type_traits>
#include <stdint.h>

template<size_t i>
struct best_type {
    typedef typename std::conditional<
        (i <= 8),
        uint8_t,
        typename std::conditional<
            (i <= 16),
            uint16_t,
            typename std::conditional<
                (i <= 32),
                uint32_t,
                uint64_t
            >::type
        >::type
    >::type type;
};

次に、次のように使用します。

#include <type_traits>
#include <iostream>
#include <stdint.h>

template<size_t i>
struct best_type {
    typedef typename std::conditional<
        (i <= 8),
        uint8_t,
        typename std::conditional<
            (i <= 16),
            uint16_t,
            typename std::conditional<
                (i <= 32),
                uint32_t,
                uint64_t
            >::type
        >::type
    >::type type;
};   

int main() {
    std::cout << sizeof(best_type<2>::type) << std::endl;
    std::cout << sizeof(best_type<8>::type) << std::endl;
    std::cout << sizeof(best_type<15>::type) << std::endl;
    std::cout << sizeof(best_type<17>::type) << std::endl;
}

ライブデモ、こちら

于 2012-08-23T00:13:49.223 に答える
4

あなたが持っているならconstexpr、これはうまくいくでしょう:

#include <climits>
#include <cstdint>
#include <cstddef>

inline
constexpr
unsigned
clz(unsigned x)
{
    return x == 0 ? sizeof(x)*CHAR_BIT : x & 0x80000000 ? 0 : 1 + clz(x << 1);
}

inline
constexpr
unsigned
clp2(unsigned x)
{
    return x == 0 ? 0 : 1 << (sizeof(x)*CHAR_BIT - clz(x-1));
}

inline
constexpr
unsigned
at_least8(unsigned x)
{
    return x < 8 ? 8 : x;
}

template<size_t Bits>
struct uint_least{};

template<>
struct uint_least<8>{ typedef std::uint8_t type; };

template<>
struct uint_least<16>{ typedef std::uint16_t type; };

template<>
struct uint_least<32>{ typedef std::uint32_t type; };

template<>
struct uint_least<64>{ typedef std::uint64_t type; };

template<size_t max>
struct uint_least_bits
{
    static const size_t value = clp2(max);
};

template<size_t max>
class A
{
    typedef typename uint_least<at_least8(uint_least_bits<max>::value)>::type underlying_type;

    underlying_type m_X;
};

int main()
{
    A<3> a;
}

がない場合はconstexpr、clp2をテンプレートメタ関数に変換できます(これは読者の演習として残されています:-))。

ああ、免責事項:32ビットを想定していますunsigned。必要に応じて、これも一般化できます。

于 2012-08-23T00:05:08.643 に答える