Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса).
Как это сделать?
Тупл отдаётся сторонней библиотекой. Хочу написать враппер, который возвращает новый. К примеру, из исходного тупла нужно получить новый в котором будут только строки и целые числа:
Типы заранее я не знаю, их будут определять пользователи фреймворка.
Контекст следующий, но не думаю что это важно: использую sqlite_orm, нужно автоматизировать создание некоторых таблиц на основе имеющихся, но с модификациями. В этом фреймворке типы нужно указать во время компиляции.
In-memory sqlite используется в качестве внутренней структуры данных при работе gui приложения. Хочу прикрутить автоматическое ведение истории изменений и автоматизировать создание undo/redo команд.
Здравствуйте, SaZ, Вы писали:
SaZ>Всем добра,
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса). SaZ>Как это сделать?
Если есть C++17, то можно как-то так — https://godbolt.org/z/E6K8Pda36
Здравствуйте, Voivoid, Вы писали:
V>Здравствуйте, SaZ, Вы писали:
SaZ>>Всем добра,
SaZ>>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса). SaZ>>Как это сделать? V>Если есть C++17, то можно как-то так — https://godbolt.org/z/E6K8Pda36 V>
Здравствуйте, Voivoid, Вы писали:
V>Здравствуйте, SaZ, Вы писали:
SaZ>>Всем добра,
SaZ>>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса). SaZ>>Как это сделать? V>Если есть C++17, то можно как-то так — https://godbolt.org/z/E6K8Pda36 V>
V>...
V>
V>В принципе можно и на C++11 написать с помощью рекурсии, но конечно кода получится побольше
Спасибо, то что надо, но я никак не могу осилить enable_if:
Здравствуйте, SaZ, Вы писали:
SaZ>Спасибо, то что надо, но я никак не могу осилить enable_if:
А другую шаблонную перегрузку отключил с соответствующим условием? См. https://godbolt.org/z/ec9rPWcEW
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).
Имплементация, конечно, несколько громоздкая, зато использование — проще некуда, по-моему.
Здравствуйте, SaZ, Вы писали:
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса). SaZ>Как это сделать?
Нечто подобное в рамках C++14 мы делали в RESTinio (объяснение можно найти здесь, раздел "Один из трюков при обработке параметров path_to_params/path_to_tuple").
Re: Создать новый std::tuple из подмножества имеющегося
SaZ>Эта перегрузка никогда не вызывается. Хотя пробовал static_assert вне этой функции — всё ок.
Сама по себе функция написана правильно. Не вызываться она может по разным причинам:
Возможно, эта функция определена не в том пространстве имен, в котором нужно, и не находится при ADL;
Возможно, существуют какие-то другие одноименные перегрузки, которые выигрывают overload resolution. Например, если в этой же области видимости определена перегрузка my_filter(T&& v), то она будет выигрывать подстановку для rvalue и неконстантных lvalue выражений (неконстантных объектов, проще говоря), использованных в качестве фактических параметров.
Могут быть и другие варианты. Чтоб диагностировать точно, желательно видеть минимальный пример, воспроиводящий проблему.
Здравствуйте, SaZ, Вы писали:
SaZ>Всем добра,
SaZ>Ломаю голову над следующей задачей. Дан некий тупл, нужно получить новый, в котором будут только определённые типы (например, унаследованные от некоего my_base класса). SaZ>Как это сделать? SaZ>Тупл отдаётся сторонней библиотекой. Хочу написать враппер, который возвращает новый. К примеру, из исходного тупла нужно получить новый в котором будут только строки и целые числа: SaZ>
SaZ>Типы заранее я не знаю, их будут определять пользователи фреймворка.
SaZ>Контекст следующий, но не думаю что это важно: использую sqlite_orm, нужно автоматизировать создание некоторых таблиц на основе имеющихся, но с модификациями. В этом фреймворке типы нужно указать во время компиляции. SaZ>In-memory sqlite используется в качестве внутренней структуры данных при работе gui приложения. Хочу прикрутить автоматическое ведение истории изменений и автоматизировать создание undo/redo команд.
такой же способ что и у rg45, только чуть другим способом
для паттерн мачинга, вместо специализаций используется перегрузка и if constexpr
для выделения элементов из паков используются шаблонные лямбды по месту
вместо std::integer_sequence используется собственный VList, но это только для наглядности, особого смысла в этом нет
в общем, для образовательных целей, думаю, эту штуку вполне можно использовать