【问题标题】:boost::mpl::equal is always false for vector and vector_cboost::mpl::equal 对于vector和vector_c总是假的
【发布时间】:2016-11-14 06:22:23
【问题描述】:

我正在尝试从 Abrahams 和 Gurtovoy 的“C++ 模板元编程”一书中重现示例“3.1 Dimensional Analysis”。有时,他们会比较一个值(mpl::vector_c 类型)的“维度”与转换后的值的“维度”相同(mpl::transform 应用于两个 mpl::vector_c)。

对我来说,比较总是false,我不明白我哪里出错了。没有转换的简化示例:

#include <iostream>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/type_index.hpp>
using boost::typeindex::type_id_with_cvr;
using namespace boost;

using X1 = mpl::vector_c<int, 1, 2, 3>;
using X2 = mpl::vector<mpl::int_<1>, mpl::int_<2>, mpl::int_<3>>;
using CMP = mpl::equal<X1, X2>;

int main() {
  std::cout << "X1: " << type_id_with_cvr<X1>().pretty_name() << std::endl;
  std::cout << "X2: " << type_id_with_cvr<X2>().pretty_name() << std::endl;
  std::cout << "CMP: " << type_id_with_cvr<CMP>().pretty_name() << std::endl;
  std::cout << "CMP::type: " << type_id_with_cvr<CMP::type>().pretty_name() << std::endl;
  std::cout << "CMP::type::value: " << CMP::type::value << std::endl;
}

从输出:

CMP: boost::mpl::equal<boost::mpl::vector_c<int, 1l, 2l, 3l, 21474
83647l, 2147483647l, 2147483647l, 2147483647l, 2147483647l, 214748
3647l, 2147483647l, 2147483647l, 2147483647l, 2147483647l, 2147483
647l, 2147483647l, 2147483647l, 2147483647l, 2147483647l, 21474836
47l, 2147483647l>, boost::mpl::vector<mpl_::int_<1>, mpl_::int_<2>
, mpl_::int_<3>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::
na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::is_s
ame<mpl_::arg<-1>, mpl_::arg<-1> > >
CMP::type: mpl_::bool_<false>
CMP::type::value: 0

【问题讨论】:

  • @jv_ 你找到了错误,谢谢。请将评论转换为答案。我想我现在可以得出一个解决方案,但是如果您知道构建用于equal 的等式谓词的正确方法,我将不胜感激。

标签: c++ boost-mpl


【解决方案1】:

好的。原因很简单。您的代码中有一个小错误。但首先让我们看看mpl::equal 语义是如何定义的:

typedef equal<Sequence1,Sequence2,Pred>::type c;

c::value == true 是且仅当 size::type::value == size::type::value 并且对于 [begin::type,end::type) i:: 中的每个迭代器 i type 等同于 advance::type >::type。

让我们检查mpl::begin&lt;X1&gt;::type::type的类型:

mpl_::integral_c<int, 1>

让我们检查mpl::begin&lt;X2&gt;::type::type的类型:

mpl_::int_<1>

如您所见,它们并不相同,但上面的定义指出,如果它应该返回 true,它们必须相同。所以让我们尝试在X2的typedef中使用intergral_c&lt;int, X&gt;而不是int_c&lt;X&gt;

瞧(注意:我在这里使用了vector3而不是vector,但这只是为了便于阅读。它也适用于mpl::vector<...>):

X1: boost::mpl::vector3_c<int, 1, 2, 3>
X2: boost::mpl::vector3<mpl_::integral_c<int, 1>, mpl_::integral_c<int, 2>, mpl_::integral_c<int, 3> >
CMP: boost::mpl::equal<boost::mpl::vector3_c<int, 1, 2, 3>, boost::mpl::vector3<mpl_::integral_c<int, 1>, mpl_::integral_c<int, 2>, mpl_::integral_c<int, 3> >, boost::is_same<mpl_::arg<-1>, mpl_::arg<-1> > >
CMP::type: mpl_::bool_<true>
CMP::type::value: 1

更新:正如您在下面的评论中看到的,用户想要比较包含的值而不仅仅是类型。以下谓词应该做用户喜欢的事情(注意:为简单起见,没有检查(例如,is_integral 等)。当然应该这样做。):

template <typename T, typename V>
struct func : boost::mpl::bool_<(T::value == V::value)> {};

为了把它传递给平等写这个:

using CMP = mpl::equal<X1, X2, func<boost::mpl::_1, boost::mpl::_2> >;

【讨论】:

  • 我不同意你的观点。 mpl_::integral_c&lt;int, 1&gt;mpl_::int_&lt;1&gt; 类型是相等的。然后我注意到@jv_ 的评论并意识到,谓词是is_same 而不是相等。这是实际的疏忽。
  • 关于更新的答案:示例谓词 func 在 boost mpl 中被称为 equal_to。我的最终解决方案是:using CMP = mpl::equal&lt;X1, X2, mpl::equal_to&lt;mpl::_1, mpl::_2&gt;&gt;;.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多