【问题标题】:Is there a typetrait checking inclusion between types?类型之间是否有类型特征检查包含?
【发布时间】:2019-01-09 11:52:13
【问题描述】:

我正在寻找一种能够知道一个类型的范围是否包含在另一个类型中的类型特征。当T 类型的每个值都可以存储为U 类型的值时,is_included_in<T,U>::valuetrue 的类型特征。示例:

is_included_in<float,double>::value; // true
is_included_in<double,float>::value; // false
is_included_in<int,double>::value; // true
is_included_in<bool,long int>::value; // true
is_included_in<long long int,float>::value; // false

Boost 中有什么东西可以做到这一点吗?还是我自己写?

注意:出于兼容性原因,我不使用 C++11。

【问题讨论】:

  • 您也许可以根据std::numeric_limits 拼凑出一些东西。应该相当容易使用它来导出比较两个整数或两个浮点类型的规则。棘手的部分是解决整数和浮点类型之间的规则。
  • @SamVarshavchik std::numeric_limits::digits 可以在这里帮助找出尾数的大小。
  • 人们不应该质疑你的问题的框架,如果它被专门标记为c++03(或c++98,基本上是一样的)。毕竟,这就是我们拥有标签的原因!
  • 我并没有考虑更好地限制问题,而是考虑接触这 69 位观察者。我知道这里的搜索引擎利用标签。它甚至可以更好地显示相关问题。另外,越具体越好,IMO 语言修订标签是其中的重要组成部分。
  • 确实如此。我不关注c++03,但我关注c++,并且在检查c++ 发布的任何问题时,我一定会寻找进一步的约束标签。我的意思是我怀疑我是唯一一个这样工作的人!请注意,这也是为什么您应该首先确保始终使用c++ - 我看到很多问题都缺少,当有c++11c++14c++17c++20 并且将始终编辑总而言之,你做对了,继续!

标签: c++ boost typetraits c++03


【解决方案1】:

不,你必须自己做。

话虽如此,如果你想使用它来使算术转换值安全,Boost 已经有numeric_cast 可以实现这一点。

因此,根据您的目标,您可能不需要特质。

至少您可以检查numeric_cast 实现并使用其原理来构建您自己的特征。

【讨论】:

  • 我认为这不能回答问题。来自 Boost 文档:numeric_cast 返回将 Source 类型的值转换为 Target 类型的值的结果。 因此,它仅检查单个值是否可以“安全”转换。但是,OP 关心源类型的所有可能的值numeric_cast 可以吗?
  • @DanielLangr 我的意思是,如果 OP 想要使用这样的假设特征作为解决方案的一部分,例如 numeric_cast,那么他们可以使用 numeric_cast。而且,否则,他们可以使用numeric_cast 的实现(至少肯定包含他们所询问的逻辑)来创建假设特征。否则答案是“不”。我觉得我涵盖了所有这些基础......
【解决方案2】:

对于基本的整数和浮点类型,您可以按如下方式比较它们的位数

template <typename T, typename U>  
struct is_included_in
  : boost::integral_constant<bool,
      std::numeric_limits<T>::digits <= std::numeric_limits<U>::digits> { };

它适用于所有典型案例。唯一的问题是它产生true,例如&lt;float, long&gt;。部分专业化在这里有帮助:

template <typename T, typename U,
  bool = boost::is_floating_point<T>::value && boost::is_integral<U>::value>
struct is_included_in
  : boost::integral_constant<bool,
      std::numeric_limits<T>::digits <= std::numeric_limits<U>::digits> { };

template <typename T, typename U>
struct is_included_in<T, U, true> : boost::false_type { };

现场演示:https://wandbox.org/permlink/NBXFOUK8fX9sxyfm

【讨论】:

  • 一个简单的检查是在条件中添加一个检查例如:is_integral&lt;T&gt;::value == is_integral&lt;U&gt;::valueis_floating_point&lt;T&gt;::value == is_floating_point&lt;U&gt;::value。如果这两个特征不可用,则可以手动创建它们。
  • @LuisMachuca 我不明白这些检查有什么用。
  • 为了防止浮点类型和整数类型之间的“包含”,它们的范围和粒度不是真正可比的(你打算把-3154.901107放在long的范围内吗?) .
  • @LuisMachuca 您的检查不包括T 是整数且U 是浮点数的情况。在我的解决方案中,您需要 3 个正面比较而不是 1 个“负面”比较。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多