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

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

03.12.2011, 00:26. Показов 2477. Ответов 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
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru