Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501

Кортежи, метафункции и все, все, все.

03.12.2011, 00:26. Показов 2501. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Цель — модифицировать заданный кортеж (например, "std::tuple") путём добавления в него новых типов или удаления существующих.

Сперва попробовал создать кортеж при помощи "boost::mpl::vector" и "boost::mpl::inherit", но проблема в том, что результат эмпээлевских метафункций неопределён, и, например, "pop_back<vector>::type" не является вектором. А мне нужно получить честный кортеж (пусть даже и сложного типа), т.к. далее нужно получить доступ к его элементам.

Решил написать свои метафункции. Вставка в начало и в конец и удаление из начала — тривиальны и компилируются за константное время — всё отлично. Но вот удаление с конца, к сожалению, так хорошо реализовать не удалось. А именно: удалось получить только линейное время.

Текст программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
 
template <typename ... Types>
struct test;
 
namespace mpl
{
    // ---- Удаление с конца ----------------------------------------------------------------------
    
    template <template <typename ...> class Class, typename HeadList, typename TailList>
    struct do_pop_back;
 
    template <template <typename ...> class Class, typename ... Head, typename Middle, typename ... Tail>
    struct do_pop_back<Class, void (Head ...), void (Middle, Tail ...)>
    {
        typedef typename do_pop_back<Class, void (Head ..., Middle), void (Tail ...)>::type type;
    };
 
    template <template <typename ...> class Class, typename ... Head, typename Tail>
    struct do_pop_back<Class, void (Head ...), void (Tail)>
    {
        typedef Class<Head ...> type;
    };
    
    template <template <typename ...> class Class, typename Only>
    struct do_pop_back<Class, void (Only), void ()>
    {
        typedef Class<> type;
    };
 
    template <typename Tuple>
    struct pop_back;
 
    template <template <typename ...> class Class, typename Head, typename ... Tail>
    struct pop_back<Class<Head, Tail ...>>
    {
        typedef typename do_pop_back<Class, void (Head), void (Tail ...)>::type type;
    };
    
    // ---- Вставка в конец -----------------------------------------------------------------------
    
    template <typename Tuple, typename Type>
    struct push_back;
    
    template <template <typename ...> class Class, typename ... Head, typename Tail>
    struct push_back<Class<Head ...>, Tail>
    {
        typedef Class<Head..., Tail> type;
    };
    
    // ---- Удаление с начала ---------------------------------------------------------------------
    
    template <typename Tuple>
    struct pop_front;
    
    template <template <typename ...> class Class, typename Head, typename ... Tail>
    struct pop_front<Class<Head, Tail ...>>
    {
        typedef Class<Tail ...> type;
    };
    
    // ---- Вставка в начало ----------------------------------------------------------------------
    
    template <typename Tuple, typename Type>
    struct push_front;
    
    template <template <typename ...> class Class, typename ... Tail, typename Head>
    struct push_front<Class<Tail ...>, Head>
    {
        typedef Class<Head, Tail ...> type;
    };
} // namespace mpl
 
int main()
{
    typedef std::tuple<int, double> tuple0;
    
    typedef mpl::pop_back<tuple0>::type tuple1;
    test<tuple1>(); // Эта штука, как вы догадались, порождает ошибку компиляции, которая печатает
                    // имя типа в явном виде.
    
    typedef mpl::push_back<tuple1, std::string>::type tuple2;
    test<tuple2>();
    
    typedef mpl::pop_front<tuple2>::type tuple3;
    test<tuple3>();
    
    typedef mpl::push_front<tuple3, bool>::type tuple4;
    test<tuple4>();
        
    return 0;
}


Итак, вопрос первый.
Может, я плохо искал? Можно ли с помощью "Буста" добиться желаемого результата?

Вопрос второй.
Есть ли идеи, как можно модифицировать метафункцию "pop_back" так, чтобы она компилировалась за константное время?

Вопрос третий.
Обратите внимание на "do_pop_back". Как думаете, православно ли подобное оперирование со списками типов (я имею в виду оборачивание в "void (...)")? По крайней мере, это лучший из пришедших в голову вариантов.
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.12.2011, 00:26
Ответы с готовыми решениями:

Переставить элементы массива так, чтобы сначала располагались все 0, затем все 1, а затем все 5
Решите задачу,не могу решить сам.В массиве X(1:n) каждый элемент равен 0, 1 или 5. Переставить элементы массива так, чтобы сначала...

Все отрицательные элементы массива перенести в начало, а все остальные в конец
Здраствуйте, помогите пожалуйста написать программу Нужно преобразовать массив Х по следующему правилу: все отрицательные элементы...

Builder C++ Мне нужна инфа все о StringGrid, и вообще все о Grid
Builder C++ Мне нужна инфа все о StringGrid, и вообще все о Grid скиньте статью а то по языку Builder C++ мало инфы :(

8
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
03.12.2011, 01:23
Цитата Сообщение от volovzi Посмотреть сообщение
Можно ли с помощью "Буста" добиться желаемого результата?
http://www.boost.org/doc/libs/... front.html
http://www.boost.org/doc/libs/... _back.html
http://www.boost.org/doc/libs/... front.html
http://www.boost.org/doc/libs/... _back.html

не?
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
03.12.2011, 01:27  [ТС]
niXman, можно скромный вопрос: ты читал сообщение?
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
03.12.2011, 01:28
и вообще, boost::mpl это в 98% полностью компайл-тайм, т.е. в рантайме ты не получишь список типов умеющий хранить значения. для этого существует boost.fusion, по истине гениальное изобретение. вся мощь компайл-тайм + отражение в ран-тайм.

Добавлено через 47 секунд
Цитата Сообщение от volovzi Посмотреть сообщение
можно кромный вопрос
вопрос во истину не скромный. читал конечно. два раза подряд.
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
03.12.2011, 01:34  [ТС]
niXman, прекрасно. В таком случае, можешь ли показать конкретный пример реализации цели? Потому что все ссылки, которые ты тут накидал, в том числе и про "Фьюжн", я исходил вдоль и поперёк, но решения там не нашёл.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
03.12.2011, 01:47
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/container/vector/vector_fwd.hpp>
#include <boost/fusion/include/vector_fwd.hpp>
 
#include <boost/fusion/algorithm/transformation/pop_back.hpp>
#include <boost/fusion/include/pop_back.hpp>
#include <boost/fusion/algorithm/transformation/push_back.hpp>
#include <boost/fusion/include/push_back.hpp>
#include <boost/fusion/algorithm/transformation/pop_front.hpp>
#include <boost/fusion/include/pop_front.hpp>
#include <boost/fusion/algorithm/transformation/push_front.hpp>
#include <boost/fusion/include/push_front.hpp>
 
#include <string>
 
namespace bf = boost::fusion;
 
template <typename ... Types>
struct test {};
 
int main() {
   typedef bf::vector<int, double> tuple0;
   
   typedef bf::result_of::pop_back<tuple0>::type tuple1;
   test<tuple1>();
 
   typedef bf::result_of::push_back<tuple1, std::string>::type tuple2;
   test<tuple2>();
   
   typedef bf::result_of::pop_front<tuple2>::type tuple3;
   test<tuple3>();
   
   typedef bf::result_of::push_front<tuple3, bool>::type tuple4;
   test<tuple4>();
     
   return 0;
}
http://liveworkspace.org/code/... ad0fba3e92

проблема-то в чем?
1
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
03.12.2011, 11:54  [ТС]
niXman, чудесно! Только как теперь создать экземпляр класса "tupleN"?
Чтобы оценить всю серьёзность вопроса, предлагаю перейти по ссылке: http://liveworkspace.org/code/... 21aa37fa0e
Это первое.

И второе: ты видимо, всё-таки невнимательно читал первое сообщение, потому что я говорил, что мне нужно получить настоящий кортеж, к элементам которого можно стандартным образом получить доступ, а не абы какой обёрточный класс.

Добавлено через 3 минуты
И ещё, товарищи, просьба всё-таки обратить внимание на второй и третий вопросы первого сообщения.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
03.12.2011, 14:54
Цитата Сообщение от volovzi Посмотреть сообщение
Только как теперь создать экземпляр класса "tupleN"?
хех! загадка

Добавлено через 1 минуту
Цитата Сообщение от volovzi Посмотреть сообщение
Чтобы оценить всю серьёзность вопроса, предлагаю перейти по ссылке
C++
1
bf::result_of::pop_back<tuple0>::type
возвращает lazy view. но вот как его использовать...

Добавлено через 2 минуты
Цитата Сообщение от volovzi Посмотреть сообщение
нужно получить настоящий кортеж
в с++ не бывает настоящих кортежей, таких, как например в пайтон. в с++ подобное реализуется при помощи гетерогенных контейнеров.
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
03.12.2011, 15:31  [ТС]
Цитата Сообщение от niXman Посмотреть сообщение
хех! загадка

Добавлено через 1 минуту

C++
1
bf::result_of::pop_back<tuple0>::type
возвращает lazy view. но вот как его использовать...
Вот видишь, не зря я спрашивал, читал ли ты первое сообщение.

в с++ не бывает настоящих кортежей, таких, как например в пайтон. в с++ подобное реализуется при помощи гетерогенных контейнеров.
Я не в курсе, что там в питоне. Под настоящим я подразумеваю любой туплоподобный контейнер, к элементам которого можно получить доступ.
Я это реализовал. Но хотел узнать, есть ли аналогичная возможность в "Бусте". Ты же накидал ссылок на известные мне решения, про которые я в самом начале сказал, что они не работают.
В общем, ясно, "Бустом" не получится. Буду пользоваться своими метафункциями.

А по другим вопросам есть мысли? Как улучшить удаление с конца?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.12.2011, 15:31
Помогаю со студенческими работами здесь

Переставить все максимальные элементы списка в его конец, все минимальные в начало
помогите плз написать программу Переставить все максимальные элементы списка в его конец ,все минимальные в начало

Переставить элементы массива так, чтобы сначала располагались все нули, затем все двойки и, наконец, все единицы
Добрый день ! У меня к вам просьба. Помогите решить задачу по с++ начинающему чайнику. :wall: Задача. В массиве A(N) каждый...

Переставить элементы массива так, чтобы сначала располагались все нули, затем все единицы, а затем все пятерки
1) В массиве X(1:n) каждый элемент равен 0, 1 или 5. Переставить элементы массива так, чтобы сначала располагались все нули, затем все...

Сначала вывести все цифры строки, а затем все остальные литеры
Помогите пожалуйста с заданием Задан текст, заканчивающийся точкой. Вывести на экран сначала все цифры, входящие в него, а затем все...

Записать в один файл все четные числа, а в другой – все нечетные
Задача: Дан файл f, все элементы которого - целые числами. Записать в один файл все четные числа, а в другой – все нечетные. Код: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
Программный отбор значений справочника
Maks 21.03.2026
Установка программного отбора значений справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru