У меня есть следующий код:
#include <boost/mpl/list_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/assert.hpp>
#include <iostream>
#include <typeinfo>
#include <assert.h>
using namespace boost::mpl;
typedef list_c<long,0,2,4,6,8,10> evens;
typedef list_c<long,2,3,5,7,11,13> primes;
typedef list_c<long,2,5,9,13,19,23> sums;
typedef transform< evens, primes, plus<> >::type result;
BOOST_MPL_ASSERT(( equal< result,sums,equal_to<_1,_2> > ));
int main()
{
std::cout << typeid(sums).name() << std::endl << typeid(result).name() << std::endl;
assert(typeid(sums) == typeid(result));
}
Он компилируется, поэтому BOOST_MPL_ASSERT имеет место. Однако при его запуске утверждение в главной функции не выполняется. Что это значит? Разве две вещи list_c (кажется, мне не хватает подходящего слова), содержащие одинаковые элементы, определяют один и тот же тип?
Спасибо за помощь.
MPL не дает никаких гарантий относительно точных типов, которые являются результатом алгоритмов MPL.
transform
выводит неопределенный тип последовательности (из integral_c<long, n>
элементы), а не list_c
,
Один из способов преобразования результата transform
в известный тип должен использовать insert_range
на list
:
insert_range<list0<>, begin<list0<> >::type, result>::type
К сожалению, это не дает list
вместо внутреннего mpl::l_item
введите, так что вам придется сделать одну и ту же операцию с обеих сторон:
BOOST_MPL_ASSERT((is_same<
insert_range<list0<>, begin<list0<> >::type, result>::type,
insert_range<list0<>, begin<list0<> >::type, sums>::type>));
Эквивалентно, вы могли бы использовать reverse_copy
в переднюю вставку:
BOOST_MPL_ASSERT((is_same<
reverse_copy<result, front_inserter<list0<> > >::type,
reverse_copy<sums, front_inserter<list0<> > >::type
>));
Действительно, потому что front_inserter
реализуется с точки зрения внутренней метафункции push_front
это дает тот же тип, что и insert_range
,
Тем не менее, проще просто положиться на copy
всегда получая один и тот же неопределенный тип последовательности:
BOOST_MPL_ASSERT((is_same<copy<result>::type, copy<sums>::type>));
И с тех пор copy
алгоритм преобразования, он возвращает тот же тип, что и transform
так что вы можете просто написать:
BOOST_MPL_ASSERT((is_same<result, copy<sums>::type>));
assert(typeid(copy<sums>::type) == typeid(result));