C++ 从类型T到类型integral的类型函数,其中sizeof(integral)>;=sizeof(T)

C++ 从类型T到类型integral的类型函数,其中sizeof(integral)>;=sizeof(T),c++,c++11,C++,C++11,我想要一个类型函数,它接受类型T并返回满足sizeof(I)>=sizeof(T)的最小整数类型I 关于如何实现这一点,有什么想法、见解或评论吗?C++11可用,欢迎使用C++14的想法 对于好奇的人: 我正在研究编程的元素。 我有一个函数,它从一个组映射到它自己,比如int。设x在函数的域内,y通过对x应用f若干次而得到。我想知道在得到y之前,我必须对x应用函数多少次。这个值称为距离,是一个整数。如果以k位指定组类型,则不同值的总数为pow(2,k)。元素之间可能的跳跃总数为pow(2,k)-

我想要一个类型函数,它接受类型T并返回满足
sizeof(I)>=sizeof(T)
的最小整数类型I

关于如何实现这一点,有什么想法、见解或评论吗?C++11可用,欢迎使用C++14的想法

对于好奇的人: 我正在研究编程的元素。 我有一个函数,它从一个组映射到它自己,比如int。设x在函数的域内,y通过对x应用f若干次而得到。我想知道在得到y之前,我必须对x应用函数多少次。这个值称为距离,是一个整数。如果以k位指定组类型,则不同值的总数为
pow(2,k)
。元素之间可能的跳跃总数为
pow(2,k)-1
。因此,与组类型大小相同的整数类型足够大,可以容纳此距离函数可能返回的所有可能距离。

这应该可以做到:

template<typename T>
struct identity {
    typedef T type;
};

template<typename T, typename Head, typename... Tail>
struct best_type {
    typedef typename std::conditional<
        sizeof(Head) >= sizeof(T), 
        identity<Head>,
        best_type<T, Tail...>
    >::type::type type;
};

template<typename T>
struct type_to_integral {
    typedef typename best_type<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t>::type type;
};
模板
结构标识{
T型;
};
样板
结构最佳类型{
typedef typename std::conditional<
sizeof(水头)>=sizeof(T),
身份
最佳类型
>::type::type type;
};
样板
结构类型\u到\u积分{
typedef typename最佳_type::type type;
};
现场演示。

这应该可以做到:

template<typename T>
struct identity {
    typedef T type;
};

template<typename T, typename Head, typename... Tail>
struct best_type {
    typedef typename std::conditional<
        sizeof(Head) >= sizeof(T), 
        identity<Head>,
        best_type<T, Tail...>
    >::type::type type;
};

template<typename T>
struct type_to_integral {
    typedef typename best_type<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t>::type type;
};
模板
结构标识{
T型;
};
样板
结构最佳类型{
typedef typename std::conditional<
sizeof(水头)>=sizeof(T),
身份
最佳类型
>::type::type type;
};
样板
结构类型\u到\u积分{
typedef typename最佳_type::type type;
};

现场演示。

这是我根据mfontanini的回答和Yakk的评论使用的示例

//In metaprogramming library header
template<bool B, typename T, typename F>
using Conditional = typename std::conditional<B,T,F>::type;

//In application header
template<typename T, typename Head, typename... Tail>
struct big_enough{
  using type =
    Conditional<sizeof(T) <= sizeof(Head),
      Head,
      typename big_enough<T, Tail...>::type
    >;
};
template<typename T, typename Head>
struct big_enough<T, Head>{
  using type = Head;
};
template<typename T>
struct containing_integer{
  using type =
    typename big_enough<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t, double>::type;
  static_assert(std::is_integral<type>::value, "Type is too large");
};

模板
结构足够大:
身份
{};
因为后者使用SFINAE

现在尝试查找大于“int64_t[2]”的整数类型时返回错误:

Transformation.cpp: In instantiation of 'struct containing_integer<long long int [2]>':
Transformation.cpp:86:54:   required from here
Transformation.cpp:33:3: error: static assertion failed: Type is too large
   static_assert(std::is_integral<type>::value, "Type is too large");
Transformation.cpp:在“包含\u整数的结构”的实例化中:
转换.cpp:86:54:从此处开始需要
Transformation.cpp:33:3:错误:静态断言失败:类型太大
静态_断言(std::is_integral::value,“类型太大”);

这很容易阅读。

这是我根据mfontanini的回答和Yakk的评论使用的示例

//In metaprogramming library header
template<bool B, typename T, typename F>
using Conditional = typename std::conditional<B,T,F>::type;

//In application header
template<typename T, typename Head, typename... Tail>
struct big_enough{
  using type =
    Conditional<sizeof(T) <= sizeof(Head),
      Head,
      typename big_enough<T, Tail...>::type
    >;
};
template<typename T, typename Head>
struct big_enough<T, Head>{
  using type = Head;
};
template<typename T>
struct containing_integer{
  using type =
    typename big_enough<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t, double>::type;
  static_assert(std::is_integral<type>::value, "Type is too large");
};

模板
结构足够大:
身份
{};
因为后者使用SFINAE

现在尝试查找大于“int64_t[2]”的整数类型时返回错误:

Transformation.cpp: In instantiation of 'struct containing_integer<long long int [2]>':
Transformation.cpp:86:54:   required from here
Transformation.cpp:33:3: error: static assertion failed: Type is too large
   static_assert(std::is_integral<type>::value, "Type is too large");
Transformation.cpp:在“包含\u整数的结构”的实例化中:
转换.cpp:86:54:从此处开始需要
Transformation.cpp:33:3:错误:静态断言失败:类型太大
静态_断言(std::is_integral::value,“类型太大”);


这很容易阅读。

您认为这将如何工作
sizeof(I)>sizeof(T)
几乎没有说明
I
应该是什么样子的,你只是想让它由一个字符数组组成吗?出于纯粹的好奇,这样的函数有什么用?我想这可以用std::enable_if和typedefs解决,但你的问题是如果sizeof(T)>8,你希望它的行为如何;顺便说一句,带字符数组的I是易于实现的。@Paranaix返回最小的整数类型
I
。包含
char
数组的
struct
不能满足这个要求。@Praetorian是的,我一眼就看不到这一点,虽然char数组可能仍然在解决他的用例(我们不知道),只是想让他知道这要容易得多。你认为这会怎样
sizeof(I)>sizeof(T)
几乎没有说明
I
应该是什么样子的,你只是想让它由一个字符数组组成吗?出于纯粹的好奇,这样的函数有什么用?我想这可以用std::enable_if和typedefs解决,但你的问题是如果sizeof(T)>8,你希望它的行为如何;顺便说一句,带字符数组的I是易于实现的。@Paranaix返回最小的整数类型
I
。包含字符数组的
struct
不能满足这个要求。@Praetorian是的,我一眼就看不到,虽然字符数组可能仍然在解决他的用例(我们不知道),只是想让他知道这要容易得多。-1还不够。
std::conditional
:-)说真的,在
type\u to\u integral
中添加另一个
std::conditional
,它将
best\u type::type
返回的类型转换为相同的有符号性,使用
make\u signed
make\u unsigned
我应该尝试一下。这是一个非常简单的答案,谢谢。虽然不是第三个条件
(我又添加了一个条件:
iIt不会优雅地失败:feed it
int64\t[2]
。添加空的
best_type
,专门继承
best_type
identity
,然后剪切样板文件并使其变得友好。不知道未使用的
typedef
和函数也会被忽略:这是标准的还是gcc优化?(哦,太棒了)@雅克:好吧,现在它用一个漂亮的
静态断言失败了
:D.-1还不够
std::conditional
:-)尽管如此,在
type\u to\u integral
中添加另一个
std::conditional
,它将
best\u type::type
返回的类型转换为相同的有符号性,使用
make\u signed
make\u unsigned
我应该尝试一下。这是一个非常简单的答案,谢谢。虽然不是第三个条件
(我又添加了一个条件:
iIt不会优雅地失败:feed it
int64\t[2]
。添加空
best\u type
,专门使用inheritanc