Сообщение Re: Создать новый std::tuple из подмножества имеющегося от 22.02.2023 2:16
Изменено 22.02.2023 10:42 rg45
Re: Создать новый std::tuple из подмножества имеющегося
Здравствуйте, SaZ, Вы писали:
SaZ>Всем добра,
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса).
SaZ>Как это сделать?
SaZ>Тупл отдаётся сторонней библиотекой. Хочу написать враппер, который возвращает новый. К примеру, из исходного тупла нужно получить новый в котором будут только строки и целые числа:
SaZ>
SaZ>Типы заранее я не знаю, их будут определять пользователи фреймворка.
Ну, как-то так. Для теcта заюзал fold expressions, поэтому C++17. Но принципиально не вижу преград для понижения до C++14
Идея такая: сначала, основываясь на типе входного тупла и списка типов-фильтров, выводим индексы элементов входного тупла, которые попадают в конечный тупл (метафункция make_filtered_index_sequence), а также тип конечного тупла (filtered_tuple_t) — все это в компайл-тайме, разумеется. После чего одним простым выражением конструируем конечный отфильтрованный тупл (make_filtered_tuple).
Имплементация, конечно, несколько громоздкая, зато использование — проще некуда, по-моему.
http://coliru.stacked-crooked.com/a/14cec1107571c9a1
SaZ>Всем добра,
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса).
SaZ>Как это сделать?
SaZ>Тупл отдаётся сторонней библиотекой. Хочу написать враппер, который возвращает новый. К примеру, из исходного тупла нужно получить новый в котором будут только строки и целые числа:
SaZ>
SaZ>std::tuple<int, string, bool, string, float> -> как получить? -> std::tuple<int, string, string>;
SaZ>
SaZ>Типы заранее я не знаю, их будут определять пользователи фреймворка.
Ну, как-то так. Для теcта заюзал fold expressions, поэтому C++17. Но принципиально не вижу преград для понижения до C++14
Идея такая: сначала, основываясь на типе входного тупла и списка типов-фильтров, выводим индексы элементов входного тупла, которые попадают в конечный тупл (метафункция make_filtered_index_sequence), а также тип конечного тупла (filtered_tuple_t) — все это в компайл-тайме, разумеется. После чего одним простым выражением конструируем конечный отфильтрованный тупл (make_filtered_tuple).
Имплементация, конечно, несколько громоздкая, зато использование — проще некуда, по-моему.
const auto tuple = std::make_tuple("Morning", 42, std::string("Hello"), 3.14, true, std::string("World"), 'A');
print(make_filtered_tuple<int, std::string>(tuple)); // -> 42, Hello, World,
print(make_filtered_tuple<double, const char*, char>(tuple)); // -> Morning, 3.14, A,
http://coliru.stacked-crooked.com/a/14cec1107571c9a1
Полный текст примера | |
| |
Re: Создать новый std::tuple из подмножества имеющегося
Здравствуйте, SaZ, Вы писали:
SaZ>Всем добра,
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса).
SaZ>Как это сделать?
SaZ>Тупл отдаётся сторонней библиотекой. Хочу написать враппер, который возвращает новый. К примеру, из исходного тупла нужно получить новый в котором будут только строки и целые числа:
SaZ>
SaZ>Типы заранее я не знаю, их будут определять пользователи фреймворка.
Ну, как-то так. Для теcта заюзал fold expressions, поэтому C++17. Но принципиально не вижу преград для понижения до C++14
Идея такая: сначала, основываясь на типе входного тупла и списка типов-фильтров, выводим индексы элементов входного тупла, которые попадают в конечный тупл (метафункция make_filtered_index_sequence), а также тип конечного тупла (filtered_tuple_t) — все это в компайл-тайме, разумеется. После чего одним простым выражением конструируем конечный отфильтрованный тупл (make_filtered_tuple).
Имплементация, конечно, несколько громоздкая, зато использование — проще некуда, по-моему.
http://coliru.stacked-crooked.com/a/14cec1107571c9a1
Если вывод типа конечного тупла в явном виде не нужен (шаблонный алиас filtered_tuple_t), то можно сделать чуть компактнее:
http://coliru.stacked-crooked.com/a/f1cb953f87844449
SaZ>Всем добра,
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса).
SaZ>Как это сделать?
SaZ>Тупл отдаётся сторонней библиотекой. Хочу написать враппер, который возвращает новый. К примеру, из исходного тупла нужно получить новый в котором будут только строки и целые числа:
SaZ>
SaZ>std::tuple<int, string, bool, string, float> -> как получить? -> std::tuple<int, string, string>;
SaZ>
SaZ>Типы заранее я не знаю, их будут определять пользователи фреймворка.
Ну, как-то так. Для теcта заюзал fold expressions, поэтому C++17. Но принципиально не вижу преград для понижения до C++14
Идея такая: сначала, основываясь на типе входного тупла и списка типов-фильтров, выводим индексы элементов входного тупла, которые попадают в конечный тупл (метафункция make_filtered_index_sequence), а также тип конечного тупла (filtered_tuple_t) — все это в компайл-тайме, разумеется. После чего одним простым выражением конструируем конечный отфильтрованный тупл (make_filtered_tuple).
Имплементация, конечно, несколько громоздкая, зато использование — проще некуда, по-моему.
const auto tuple = std::make_tuple("Morning", 42, std::string("Hello"), 3.14, true, std::string("World"), 'A');
print(make_filtered_tuple<int, std::string>(tuple)); // -> 42, Hello, World,
print(make_filtered_tuple<double, const char*, char>(tuple)); // -> Morning, 3.14, A,
http://coliru.stacked-crooked.com/a/14cec1107571c9a1
Полный текст примера | |
| |
Если вывод типа конечного тупла в явном виде не нужен (шаблонный алиас filtered_tuple_t), то можно сделать чуть компактнее:
http://coliru.stacked-crooked.com/a/f1cb953f87844449
Без вывода типа тупла | |
| |