Повышение mpl-трансформированной последовательности «real» тип

Смотрите следующий код в документации по mpl-преобразованию boost:

typedef vector<char,short,int,long,float,double> types;
typedef vector<char*,short*,int*,long*,float*,double*> pointers;
typedef transform< types,boost::add_pointer<_1> >::type result;
BOOST_STATIC_ASSERT(( equal<result,pointers>::value ));

Я хочу понять систему типов boost::mpl и «как это на самом деле работает».
Насколько я понимаю mpl::equal просто сравниваются элементы следующих двух последовательностей, а не сами типы целых последовательностей.
Я не понимаю, почему не получается следующее:

BOOST_STATIC_ASSERT(( std::is_same<result,pointers>::value )); //< assert fails

Почему тип результата не на 100% идентичен типу «указатели»?
Я предполагаю, что это как-то потому, что mpl выполняет преобразование ленивый или результат просто последовательность, а не вектор больше?
Можно ли как-то заставить mpl больше не быть ленивым и получить 100% идентичный тип (я мог бы написать функцию преобразования сам с этим результатом, но я хочу знать, как это сделать в mpl)?

Я уже пробовал некоторые вещи, например, например вставить результат в новый вектор, но безуспешно:

BOOST_STATIC_ASSERT(( std::is_same<
mpl::insert_range< mpl::vector<>, mpl::begin<mpl::vector<> >::type,
result >::type, pointers >::value )); //< assert fails too

Кроме того, я попытался использовать back_insert в функции преобразования, которая тоже не работает:

typedef transform< types,boost::add_pointer<_1>,
mpl::back_inserter< mpl::vector< > > >::type result_new;
BOOST_STATIC_ASSERT(( std::is_same<result_new,pointers>::value )); //< fails...

Чтение «документации» мне не помогло.
Итак, еще раз, возможно ли получить 100% идентичный тип с помощью преобразования mpl (или любых других функций последовательности преобразования)? И каков результат типа

result

«на самом деле», когда это не is_same с указателями?

4

Решение

Еще раз спасибо @llonesmiz за код, который прекрасно печатает типы, используя typeid (), который помог понять, что происходит.

Таким образом, кажется, что реальный тип результата зависит от компилятора (вероятно, boost #ifdefs), компилятор Intel и Visual Studio преобразуют его обратно в std :: vectorN.<> где максимальное N — это заранее заданное число в boost (поэтому оно не работает, когда N слишком велико).
Для g ++ генерируется искаженный тип (даже 2 разных типа из моих вызовов преобразования).

Так что я думаю, проверка типа через mpl :: equal — это хорошо (проверьте элементы диапазонов).
Если все типы должны быть «действительно» эквивалентными (имеет место std :: is_same), я полагаю, вам нужно преобразовать результат вручную в переменный класс шаблона std :: tuple.

Увидеть http://liveworkspace.org/code/3l8O9K$ 16 Пример кода

или короче говоря:

template < class T, class R >
struct ToStdTuple;

template < class... TTypes, class X >
struct ToStdTuple< std::tuple< TTypes... >, X >
{
typedef std::tuple< TTypes..., X > type;
};

а потом

// typedef mpl::vector<char,short,int,long,float,double> types;
// typedef mpl::transform< types,boost::add_pointer<mpl::_1> >::type result;

typedef mpl::fold< result, std::tuple<>,
ToStdTuple< mpl::_1, mpl::_2 > >::type result_normalized;

в результате чего

std::tuple<char*, short*, int*, long*, float*, double*>

для всех вызовов преобразования

7

Другие решения

Других решений пока нет …