我尝试制作index_type_<N>
类型,该类型将根据type
返回索引的N
,其中N
是索引的最大数量可以去。
例如:
index_type_<32>::type index1; //uint8_t
index_type_<64000>::type index2; //uint16_t
index_type_<18446744073709551>::type index3; //uint64_t
我有以下代码拒绝编译,我无法在错误消息中搜索Google,但我无法确定原因,但这些代码似乎与我的情况无关。
#include <iostream>
template<size_t N, typename T = void>
struct index_type_;
template<size_t N>
struct index_type_<N, typename std::enable_if<N <= 256, uint8_t>::value>
{
typedef uint8_t type;
};
template<size_t N, typename T = void>
struct index_type_;
template<size_t N>
struct index_type_<N, typename std::enable_if<N <= 65536, uint16_t>::value>
{
typedef uint16_t type;
};
template<size_t N>
struct index_type_<N, typename std::enable_if<N <= 4294967296, uint32_t>::value>
{
typedef uint32_t type;
};
template<size_t N>
struct index_type_<N, typename std::enable_if<N <= 18446744073709551616ULL, uint64_t>::value>
{
typedef uint64_t type;
};
int main()
{
index_type_<32>::type index1;
index_type_<232122>::type index2;
index_type_<992532523>::type index3;
index_type_<4213662352328854>::type index4;
std::cout << "index1:" << sizeof(index1) << std::endl;
std::cout << "index2:" << sizeof(index2) << std::endl;
std::cout << "index3:" << sizeof(index3) << std::endl;
std::cout << "index4:" << sizeof(index4) << std::endl;
}
错误和示例代码可以在这里找到:
任何帮助都会非常感激,我觉得我错过了一些明显的东西。
答案 0 :(得分:6)
您的所有专业都不明确。例如。哪一个是以下的最佳选择?
template <std::size_t N>
struct Foo {
// Specialization 1
};
template <std::size_t N>
struct Foo<N> {
// Specialization 2
};
int main() {
Foo<1> foo; // Error: partial specialization 'Foo<N>' does not
// specialize any template arguments.
}
尝试这样的事情:
template <std::uintmax_t N>
struct index_type {
using type = std::conditional_t<N <= 255, std::uint8_t,
std::conditional_t<N <= 63535, std::uint16_t,
std::conditional_t<N <= 4294967295, std::uint32_t,
std::conditional_t<N <= 18446744073709551615ULL, std::uint64_t,
std::uintmax_t>>>>;
};
template <std::uintmax_t N>
using index_type_t = typename index_type<N>::type;
用法:
index_type_t<64000> test; // unsigned int
答案 1 :(得分:3)
通过numeric_limits
使用类型列表和递归测试:
#include <cstdint>
#include <limits>
#include <type_traits>
namespace detail
{
template<class T>
struct delay { using type = T; };
template<class T, T t, class... IntTypes>
struct select_int_type
{
static_assert(sizeof...(IntTypes) > 0,
"No integer type sufficiently big found.");
};
template<class T, T t, class Head, class... Tail>
struct select_int_type<T, t, Head, Tail...>
{
using type = typename std::conditional<
t <= std::numeric_limits<Head>::max()
, delay<Head>
, select_int_type<T, t, Tail...>
>::type::type;
};
}
template<std::uintmax_t N>
using select_uint_type =
typename detail::select_int_type<decltype(N), N,
std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t
, std::uintmax_t
>::type;
用法示例:
#include <iostream>
int main()
{
select_uint_type<32> index1;
select_uint_type<232122> index2;
select_uint_type<992532523> index3;
select_uint_type<4213662352328854> index4;
std::cout << "index1:" << sizeof(index1) << std::endl;
std::cout << "index2:" << sizeof(index2) << std::endl;
std::cout << "index3:" << sizeof(index3) << std::endl;
std::cout << "index4:" << sizeof(index4) << std::endl;
}
您可以通过其他别名模板轻松添加签名类型:
template<std::intmax_t N>
using select_int_type =
typename detail::select_int_type<decltype(N), N,
std::int8_t, std::int16_t, std::int32_t, std::int64_t
, std::intmax_t
>::type;
(我认为make_signed
因为基于值的选择而存在问题