2016-11-14 72 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