шаблон С++: boost::mpl::transform с параметром шаблона шаблона

Теперь, когда на мой предыдущий вопрос есть решение, возникает больше вопросов.

Я хочу использовать метафункцию wrap_into_container с boost::mpl::transform, например:

#include <vector>
#include <list>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/mpl/transform.hpp>

namespace container
{
    template <typename T> struct vector { typedef std::vector<T> type; };
    template <typename T> struct list   { typedef std::list<T> type; };
}

template<typename T, template <typename> class Container>
struct wrap_into_container
{
    typedef typename Container<T>::type type;
};

int main()
{
    namespace fusion = boost::fusion;
    namespace mpl = boost::mpl;

    typedef fusion::vector<int, float, int> vec_type;
    typedef mpl::transform< vec_type, wrap_into_container<mpl::_1, container::vector> >::type wrapped_vec_type;

    wrapped_vec_type w;
    return w.size();
}

Ссылка на coliru

Но похоже, что я не могу передать параметр шаблона шаблона в mpl::transform...

Как я могу это решить? Пожалуйста, предоставьте решение C++03, так как я не могу использовать C++11.


person m.s.    schedule 17.04.2014    source источник
comment
wrap_into_container<mpl::_1, container::vector> — это обычный тип, а ::type — это std::vector<mpl::_1>, верно? Итак, о каком параметре шаблона шаблона вы говорите?   -  person iavr    schedule 17.04.2014
comment
Второй аргумент шаблона wrap_into_container — это параметр шаблона шаблона. Итак, правильная формулировка: я не могу передать лямбда-выражение в mpl::transform, которое зависит от параметра шаблона шаблона.   -  person m.s.    schedule 17.04.2014


Ответы (2)


В boost::mpl функции более высокого порядка записываются путем передачи фиксированного типа с внутренним элементом шаблона apply (известным как класс метафункции), а не с помощью параметров шаблона-шаблона. Живой пример.

#include <vector>
#include <list>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/mpl/transform.hpp>
#include <iostream>

namespace container
{
    struct vector {
        template<typename T> struct apply {
            typedef std::vector<T> type;
        };
    };
    struct list   {
        template <typename T> struct apply {
            typedef std::list<T> type;
        };
    };
}

template<typename T, typename ContainerMaker>
struct wrap_into_container
{
    typedef typename ContainerMaker::template apply<T>::type type;   
};

int main()
{
    namespace fusion = boost::fusion;
    namespace mpl = boost::mpl;

    typedef fusion::vector<int, float, int> vec_type;
    typedef mpl::transform<
        vec_type,
        wrap_into_container<mpl::_1, container::vector>
    >::type wrapped_vec_type;

    wrapped_vec_type w;
    std::cout << size(w) << "\n";
    return size(w);

}
person Mankarse    schedule 17.04.2014
comment
Спасибо! Теперь, когда вы назвали его, я также нашел соответствующую документацию по повышению по адресу boost.org/doc/libs/1_55_0/libs/mpl/doc/tutorial/ - person m.s.; 17.04.2014

Я не знаю boost::mpl, поэтому могу только строить догадки на основании того, что видел в документации.

Я думаю, что вам нужно

template<template <typename> class Container>
struct wrap_into_container
{
    template<typename T>
    struct map
    {
        typedef typename Container<T>::type type;
    };
};

С последующим

typedef wrap_into_container<container::vector>::template map<mpl::_1> fun;
typedef transform<vec_type, fun>::type wrapped_vec_type;

В этом случае fun — это класс формы C<mpl::_1>, где C — это шаблон класса, а ::type — это std::vector<mpl::_1>. Я думаю, это то, что mpl::transform ожидает от своей карты типов.

Мой единственный тест — моя собственная версия transform, которая работает с аргументами шаблона вместо заполнителей для карты типов. Посмотрите живой пример, где transform определено с помощью C++11, а остальная часть написана на C. ++03. В этом примере я использую только

wrap_into_container<container::vector>::template map

в качестве аргумента шаблона шаблона для моего transform без заполнителя <mpl::_1>.

Надеюсь, это поможет.

person iavr    schedule 17.04.2014
comment
Это тоже работает, но принятый ответ показывает, как это сделать boost::mpl-способ. - person m.s.; 17.04.2014
comment
@РС. Хорошо, приятно знать. На мгновение я испугался и удалил свой ответ, но еще раз взглянув на документацию, я был уверен, что он действителен, поэтому я восстановил его :-) - person iavr; 17.04.2014