对于vector和vector_c,boost :: mpl :: equal总是为false

时间:2016-11-14 06:22:23

标签: c++ boost-mpl

我试图从Abrahams和Gurtovoy的书“C ++ Template Metaprogramming”中重现“3.1维分析”的例子。在某些时刻,他们会比较值(类型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

1 个答案:

答案 0 :(得分:1)

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

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

c :: value == true且仅当size :: type :: value == size :: type :: value并且对于[begin :: type,end :: type]中的每个迭代器i ::类型与advance&lt;相同begin :: type,distance&lt; begin :: type,i&gt; :: type&gt; :: type。

让我们检查mpl::begin<X1>::type::type的类型:

mpl_::integral_c<int, 1>

并让我们检查mpl::begin<X2>::type::type的类型:

mpl_::int_<1>

如你所见,它们不一样,但上面的定义表明它们必须是相同的,如果它应该返回true。因此,我们尝试在intergral_c<int, X>的typedef中使用int_c<X>而不是X2

Voila(注意:我在这里使用了vector3而不是矢量,但只是为了便于阅读。它也适用于mpl :: vector&lt; ...&gt;):

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> >;