2016-11-14 69 views
1

我试图从Abrahams和Gurtovoy的书“C++ Template Metaprogramming”中重新生成一个例子“3.1 Dimensional Analysis”。在某个时刻,他们比较了值(类型mpl::vector_c)的“维度”与变换值的“维度”相同(mpl::transform应用于两个mpl::vector_c)。boost :: mpl :: equal对于vector而言总是为false 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 
+0

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

回答

1

确定。原因很简单。你的代码有一个小小的错误。但是,首先让我们来看看如何在mpl::equal语义定义:

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

Ç::值==真正是且仅当大小::类型::值==大小::类型::值并且对于[begin :: type,end :: type)中的每个迭代器,i :: type与预先< begin :: type,距离< begin :: type,i> :: type> :: type是相同的。

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

mpl_::integral_c<int, 1> 

,并让检查mpl::begin<X2>::type::type类型:

mpl_::int_<1> 

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

瞧(注:我用的Vector3在这里,而不是一个向量,但只是为了可读性它还将与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 

UPDATE:正如您在下面的注释中看到的,用户想要比较包含的值而不仅仅是类型。继谓语应该做用户喜欢什么(注意:为了简单起见,没有检查(例如,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> >; 
+0

我不同意你的看法。类型'mpl _ :: integral_c '和'mpl _ :: int_ <1>'是相等的。然后我注意到@jv_的评论,并意识到,谓词是“is_same”,而不是一个平等。这是实际的监督。 – olpa

+0

关于更新的答案:示例谓词'func'在boost mpl中被称为'equal_to'。我的最终解决方案是:'使用CMP = mpl :: equal >;'。 – olpa