Превращение boost :: tuples :: cons <...> обратно в соответствующий boost :: tuple <...> - PullRequest
3 голосов
/ 25 октября 2010

Для небольшого библиотечного проекта я использую boost :: tuple. Прямо сейчас я сталкиваюсь с проблемой превращения «списка минусов», над которым я работал через метапрограммирование, обратно в тип boost :: tuple <...>. «Грязное» решение состоит в том, чтобы обеспечить множество частичных специализаций а-ля

template<class T> struct id{typedef T type;};

template<class TL> struct type_list_to_tuple_type;

template<class T1>
struct type_list_to_tuple_type<
    boost::tuples::cons<T1,boost::tuples::null_type>
> : id<boost::tuple<T1> > {}

template<class T1, class T2>
struct type_list_to_tuple_type<
    boost::tuples::cons<T1,
    boost::tuples::cons<T2,boost::tuples::null_type> >
> : id<boost::tuple<T1,T2> > {}

template<class T1, class T2, class T3>
struct type_list_to_tuple_type<
    boost::tuples::cons<T1,
    boost::tuples::cons<T2,
    boost::tuples::cons<T3,boost::tuples::null_type> > >
> : id<boost::tuple<T1,T2,T3> > {}

...

Но это утомительно и подвержено ошибкам, особенно потому, что мне нужна поддержка кортежей с возможно большим количеством элементов. Эти типы кортежей генерируются автоматически при перегрузке оператора. Если возможно, я бы хотел избежать необходимости писать так много специализаций.

Есть идеи, как это сделать без каких-либо функций C ++ 0x? Я полагаю, это невозможно. Но, может быть, я что-то упускаю.

Редактировать: Я на самом деле пробовал это с экспериментальной поддержкой C ++ 0x, только чтобы выяснить, что она еще не работает:

template<class TPH>
class type_pack_holder_to_tuple_type;

template<class...Types>
class type_pack_holder_to_tuple_type<
        type_pack_holder<Types...> >
: id< boost::tuple<Types...> > {};

G ++ 4.5.1 говорит:

sorry, unimplemented: cannot expand 'Types ...' into
a fixed-length argument list

: - (

Ответы [ 2 ]

3 голосов
/ 25 октября 2010

Если вы занимаетесь метапрограммированием шаблонов и вам нужно преобразование из списков типов в кортеж, возможно, вам следует рассмотреть возможность использования Boost.MPL и Boost.Fusion .Первый обеспечивает набор контейнеров и алгоритмов времени компиляции для манипулирования списком времени, а второй устанавливает связь между чистым временем компиляции (MPL) и чистым временем выполнения (STL), предоставляя «гибридные» контейнеры и алгоритмы, которые могут бытьработали либо во время компиляции посредством метапрограммирования шаблона, либо во время выполнения в виде кортежей.

Однако, чтобы ответить на ваш вопрос, я не думаю, что вам нужно преобразовывать ваш список минусов в кортеж, поскольку класс кортежатолько удобство, чтобы объявить кортеж легче.Фактически, кортеж просто наследует из соответствующего списка минусов, например, tuple<int, float> наследует от cons<int, cons<float, null_type> > без добавления каких-либо данных или функций-членов.Таким образом, в основном, когда вы объявляете tuple, библиотека «создает» соответствующий список минусов;поскольку вы уже создаете свой собственный список минусов, вам больше не нужен класс кортежа.

0 голосов
/ 25 октября 2010

Ясно, что ответ на ваш вопрос связан с Boost.Preprocessor .Перечисление параметров шаблона является своего рода специальностью!

Посмотрите на BOOST_PP_LOCAL_ITERATE, BOOST_PP_ENUM_PARAMS и BOOST_PP_N_PARAMS.Они ключ.

BOOST_PP_REPEAT и BOOST_PP_COMMA_IF могут также оказать некоторую помощь.

...