条件付きではどうですか?
#include <vector>
#include <cstdint>
#include <iostream>
#include <type_traits>
template <std::size_t N>
struct foo
{
static_assert(N < 65U, "foo 64 limit");
using vType = typename std::conditional<
(N < 9U), std::uint8_t,
typename std::conditional< (N < 17U), std::uint16_t,
typename std::conditional< (N < 33U), std::uint32_t, std::uint64_t
>::type>::type>::type;
std::vector<vType> data;
};
int main()
{
static_assert(1U == sizeof(foo<1>::vType), "!");
static_assert(1U == sizeof(foo<8>::vType), "!");
static_assert(2U == sizeof(foo<9>::vType), "!");
static_assert(2U == sizeof(foo<16>::vType), "!");
static_assert(4U == sizeof(foo<17>::vType), "!");
static_assert(4U == sizeof(foo<32>::vType), "!");
static_assert(8U == sizeof(foo<33>::vType), "!");
static_assert(8U == sizeof(foo<64>::vType), "!");
// foo<65> f65; compilation error
}
それとも、もっとエレガントな方法(私見)、あなたはリストの最初の有用なタイプを選択します(以下の例ではselectTypeByDim
、)タイプの特性を定義することができますに
#include <tuple>
#include <vector>
#include <cstdint>
#include <climits>
#include <type_traits>
template <std::size_t N, typename T,
bool = (N <= sizeof(typename std::tuple_element<0U, T>::type)*CHAR_BIT)>
struct stbdH;
template <std::size_t N, typename T0, typename ... Ts>
struct stbdH<N, std::tuple<T0, Ts...>, true>
{ using type = T0; };
template <std::size_t N, typename T0, typename ... Ts>
struct stbdH<N, std::tuple<T0, Ts...>, false>
{ using type = typename stbdH<N, std::tuple<Ts...>>::type; };
template <std::size_t N, typename ... Ts>
struct selectTypeByDim : stbdH<N, std::tuple<Ts...>>
{ };
template <std::size_t N>
struct foo
{
static_assert(N < 65U, "foo 64 limit");
using vType = typename selectTypeByDim<N,
std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t>::type;
std::vector<vType> data;
};
int main()
{
static_assert(1U == sizeof(foo<1U>::vType), "!");
static_assert(1U == sizeof(foo<CHAR_BIT>::vType), "!");
static_assert(2U == sizeof(foo<CHAR_BIT+1U>::vType), "!");
static_assert(2U == sizeof(foo<(CHAR_BIT<<1)>::vType), "!");
static_assert(4U == sizeof(foo<(CHAR_BIT<<1)+1U>::vType), "!");
static_assert(4U == sizeof(foo<(CHAR_BIT<<2)>::vType), "!");
static_assert(8U == sizeof(foo<(CHAR_BIT<<2)+1U>::vType), "!");
static_assert(8U == sizeof(foo<(CHAR_BIT<<3)>::vType), "!");
//foo<(CHAR_BIT<<3)+1U> f65; compilation error
}
このような 'vector'sのユースケースは何ですか? ['std :: bitset'](http://en.cppreference.com/w/cpp/utility/bitset)はあなたの問題を解決しますか? –
結果のベクトルをソートしたいので、ビットセットは実現できません。 – eclipse
さらにいくつかの文脈を与える:これは、4文字のアルファベット(ゲノム)から固定長の何十億もの文字列を表現するクラスです。 Nは文字数、最大値は32です.4のアルファベットのうち32文字は64ビットで表現できます。したがってベクターは基本的に小さなゲノムサンプルがたくさんあり、それらのサンプルのサイズは一般的でなければなりません。 – eclipse