|
протащить константу из runtime'a в мета-мир
|
|||
---|---|---|---|
#18+
Всем привет! Несколько дней уже бьюсь с одной проблемой идеи иссякли и начинаю ходить кругами. Скорее всего уже просто замылил все что можно и нельзя и не вижу какого-то адекватного решения, поэтому прошу помощи в одном важном для меня вопросе. Предположим есть системная (не зависящая от меня) функция foo(). В результате своей работы, помимо всего прочего, она возвращает некую заранее определенную константу. Это может быть просто #define переменная или enum тип - не суть важно. Важно что это - константа известная на этапе компиляции! Я хочу создать расширяемый (разработчиком) массив объектов, поведение которых должно определяться значением данной константы. То есть, после отработки foo мы получаем данную константу, сохраняем ее в виде constexpr значения внутри динамически сгенерированной структуры и потом используем ее для выполнения какой-то специфической работы, в том числе и compile time. Все пока просто, с одним условием - сгенерированный объект, хранящий эту переменную, не должен быть шаблонным. Потому что я хочу иметь возможность собрать их в один общий контейнер, например, std::vector, создав таким образом кэш. Как это должно выглядеть с точки зрения идеальной реализации Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
формирование массива... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
дальше, в некоторой функции bar, которая ближе к клиенту Код: plaintext 1. 2. 3. 4. 5. 6. 7.
Выйти из ситуации можно просто: создать bar как non-type template функцию и заставить пользователя самому руками передавать правильную цифру 1, 2, 3 и тд... Хоть это и панацея для меня, как создателя библиотеки, но это - уродство потому что 1, с точки зрения архитектуры я уже знаю какая должна быть цифра, т.к. получил ее когда-то раньше от foo и могу даже таскать ее с собой в качестве runtime значения внутри Value-объекта (но хочу таскать ее с собой в виде compite time значения, чтобы использовать в различных constexpr вычислениях и проверках, коих будет несколько больше чем в этом абстрактном примере) 2. с точки зрения надежности пользователь может ввести все что угодно, чего быть не должно, а проверить это получится только в runtime что я уже попробовал, но везде обломался по той или иной причине: * создать для Value шаблонный базовый класс и передавать в него значение из коструктора Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
* создать обычную переменную/объект членом Value и генерировать ее значение в конструкторе, но тогда как в каком виде ее объявить в самом Value, если у нее должен быть динамически определяемый тип хранимых данных Код: plaintext 1. 2. 3. 4. 5. 6. 7.
* из предыдущего вытекает потребность в template variable (c++14) внутри объекта Value Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
компилятору это тоже не нравится, ему надо чтобы я не затягивал с инициализацией static значения, либо он говорит, что не могу проинициализоровать это в конструкторе я точно не хочу использовать type erasure, std::any, std::variant и любое другое, что требует динамического выделения памяти, потому что как раз от него и пытаюсь уйти. И пока все замечательно получается, и осталось совсем чуть чуть, фактически эта проблема - последнее, что мешать закончить работу над данной библиотекой и начать ей пользоваться, но застрял, казалось бы на пустом месте. Вот Если кто подскажет что-то дельное буду премного благодарен -------------------------------------------------------------- o(O_O)o ... |
|||
:
Нравится:
Не нравится:
|
|||
18.03.2020, 10:57 |
|
протащить константу из runtime'a в мета-мир
|
|||
---|---|---|---|
#18+
Cerebrum Все пока просто, с одним условием - сгенерированный объект, хранящий эту переменную, не должен быть шаблонным. Потому что я хочу иметь возможность собрать их в один общий контейнер, например, std::vector, создав таким образом кэш. 1. Сделай свой контейнер для контейнеров? Вот это было бы классно, потому что я когда маялся темой про динамическую типизацию на момент компиляции, много читал интернеты, и понял, что никто, и даже я не осилил нормально статический type erasure(просто потому что он противоречит нормальной логике). 1. А что там с boost::any? (сам не видел) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.03.2020, 06:06 |
|
протащить константу из runtime'a в мета-мир
|
|||
---|---|---|---|
#18+
CEMbОтнаследуй шаблон от интерфейса? про наследование уже писал ниже. можешь привести свой пример? Если речь про virtual базовый класс, то тут без динамики никак, а значит, проще взять type erasure. Да и даже если взять, что это даст? Это все runtime темы. Можно будет дернуть функцию производного через базовый без знания конкретики производного, а мне не нужно функцию, мне надо к compile-time константе доступ получить и проверить ее в compile-time, чуть позже чем она фактически появилась - вот что самое сложное CEMbСделай свой контейнер для контейнеров? Думал об этом, но пока по временным трудозатратам это неоправдано, да и с самой архитектурой есть неоднозначности. Какой она должна быть? Шаблоны не подходят, иначе я бы взял любой из std. Что еще остается? Что именно должен хранить этот контейнер? По факту это должны быть разнородные объекты типа template <int> object, то есть по факту размер их будет фиксированным, а вот тип - нет. Можно, конечно, заморочится, но пока решил зайти с другого фланга, может удастся вынести switch куда-то ближе к клиентскому коду, но при это скрыв реализацию внутри, и не заставлять пользователя вызывать bar в стиле double d = obj.bar<double, 1, 2, 3...>(.....) CEMbboost::any? а что с ним? подозреваю тоже самое что и с std::any, а про него уже написал. boost'ом не пользуюсь и всегда обходил этот тестовый полигон std за километр, т.е. тащить его в проект ради одной фичи... ну, такое себе CEMbне осилил нормально статический type erasure подозреваю, что статический type erause возможен, только в статически выделенной памяти , то есть для объектов с заранее известным размером и выравниванием. И сводится, как правило, к имитации таблицы виртуальных ф-ций, а ля trampoline (см. Davide Di Gennaro - Advanced Metaprogramming in Classic C++), [spoiler] Антон Полухин про fast pimpl ... |
|||
:
Нравится:
Не нравится:
|
|||
19.03.2020, 09:18 |
|
протащить константу из runtime'a в мета-мир
|
|||
---|---|---|---|
#18+
Cerebrum я точно не хочу использовать type erasure, std::any, std::variant и любое другое, что требует динамического выделения памяти В std::any должен быть small object optimization. std::variant вообще не использует кучу. На вашем месте я бы использовал std::variant и std::visit для матчинга. Тогда компилятор все по максимуму вытянет в компайл-тайм. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.03.2020, 15:55 |
|
протащить константу из runtime'a в мета-мир
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky std::variant и std::visit тоже думал про это но пока родилась идея, вечером проверять буду ... |
|||
:
Нравится:
Не нравится:
|
|||
19.03.2020, 17:00 |
|
протащить константу из runtime'a в мета-мир
|
|||
---|---|---|---|
#18+
Cerebrum про наследование уже писал ниже. можешь привести свой пример? да, тут динамика да тут всё просто, вот у меня была реализация "различных" параметров, примерно такая: интерфейс: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
И сам шаблон, примерно: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
и потом ещё кучка реализаций работы с разными типами через строку. Т.о. строка тут играет роль type erase Ну и в контейнер складываются указатели на IParam Cerebrum проще взять type erasure Вообще, нормальный type erase (для stl-я) невозможен в принципе. При складировании вы избавляетесь от типа. Но когда вам надо что-то сделать с этим объектом... вы уже не знаете, кто он, и вот тогда начинаются хаки с извлечением типа... Cerebrum тащить его в проект ради одной фичи... ну, такое себе Cerebrum подозреваю, что статический type erause возможен, только в статически выделенной памяти , то есть для объектов с заранее известным размером и выравниванием. И сводится, как правило, к имитации таблицы виртуальных ф-ций, а ля trampoline (см. Davide Di Gennaro - Advanced Metaprogramming in Classic C++), ... |
|||
:
Нравится:
Не нравится:
|
|||
20.03.2020, 06:00 |
|
|
start [/forum/topic.php?fid=57&msg=39938952&tid=2017460]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
36ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
49ms |
get tp. blocked users: |
1ms |
others: | 273ms |
total: | 398ms |
0 / 0 |