|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Проблема решилась переносом using-ов в хвост класса. Видимо, как-то так работает построитель классов, видимость устанавливается после того, как развернут метод, а не до того. Ну, т.е. можно и до того, но это должен быть готовый метод в классе-предке. А тут его ещё не было. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.05.2019, 12:50 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMb, если я правильно понял вы хотите использовать класс для хранения значений и извлекать их указывая тип. В случае если типы хранимых значений внутри класса Param уникальные (а иначе как определить какое именно из 2-х или более значений одинаковых типов нужно извлечь?) то почему не использовать std::tuple ? Он как раз умеет жранить произвольный состав параметров и извлекать их данные по их типу и еще вместо return 0 лучше использовать return {}, поскольку возвращаемое значение не обязательно будет интегральным типом, но также и классом ... |
|||
:
Нравится:
Не нравится:
|
|||
20.05.2019, 12:56 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Cerebrum, нет, я хочу хранить множества параметров разных типов в одной коробке. Сейчас я указываю типы параметров, которые лежат в коробке: <int, float, string> - в качестве параметров шаблона. - множество типов заранее известно - количество элементов заранее не известно - всё на момент компиляции обычно это классическая задача с одним классом-предком и кучей наследников, тип определяется динамически, в контейнере хранятся указатели на объекты класса-предка. Но я хочу сделать типизацию на момент компиляции, так как мы там знаем, какие типы мы складываем в коробку, почему бы это не использовать сразу? минусы такие: нету единого итератора, нету порядка зато есть такой плюс: всё автоматически сортируется по типам ну и хочется сделать так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
ну и там, на самом деле не просто значения, а то, что приходит в ParamAdd, оборачивается в некий класс, который как-то работает с этим параметром (ограничения, жизненный цикл, и прочее) Cerebrumвместо return 0 лучше использовать return {}это просто заглушка для демонстрации была, там возвращается или параметр-обёртка или значение параметра. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.05.2019, 20:23 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Неужели никому не надо? Ок, у меня получилось. Идея избавления была такая: использовать оператор каста на некотором объекте, который возвращается из ParamGet, когда не указан шаблонный параметр. Объект в частном случае вышел такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
последний оператор - частный случай, но его можно и оставить, он ничему не противоречит. получилось даже лучше: Код: plaintext 1. 2. 3. 4. 5. 6.
т.е. у меня функция возвращает ровно тот тип, что указан слева, ура! "лучше", в смысле, у меня тут метод AnyGet, возвращающий "всё", потому что ParamGet через uning проброшен по всей иерархии, и попытки использовать его без шаблона приводят к неоднозначности, а AnyGet должен "быть" только в "последнем" классе: Код: plaintext 1. 2. 3. 4.
(хотя он есть везде, просто невидим) если кто знает, как это можно сделать одним методом, подскажите :) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.05.2019, 13:51 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
добрый день где в стандарте почитать про создание и порядок выполнения преобразований, когда используются шаблоны? ситуация такая у меня - есть класс std::string - есть мой класс А, где есть шаблонный оператор (T), кастующий что-то там своё в Т, ок. теперь, если я напишу так в коде: Код: plaintext 1. 2. 3.
я получу ошибку про то, что компилятор не может найти в string оператор = для правого операнда. явный каст решает проблему Код: plaintext 1.
но это некрасиво (и неудобно, у меня много объектов А и работы с ними, везде писать в коде явные касты нехорошо) если же я напишу в класса А явный каст: Код: plaintext 1.
то всё ок Хмм. Почему в первом случае компилятор не генерит из шаблона оператор для каста в стринг? А не хочу писать в коде А явный каст, потому что А может работать с любым типом, мне придётся по мере надобности все их вписывать в код, это очень нехорошо. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.07.2019, 07:07 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMbПочему в первом случае компилятор не генерит из шаблона оператор для каста в стринг?потому что там не стринг. Помог шаблонный оператор каста в ссылку на T. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.07.2019, 07:13 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMb Код: plaintext 1. 2. 3.
Почему ... компилятор не генерит из шаблона оператор для каста в стринг? Код: plaintext 1. 2. 3. 4. 5.
А почему он должен генерить шаблон для каста в стринг а не в const char* или std::initializer_list<char>? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2019, 04:47 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a.guestА почему он должен генерить шаблон для каста в стринг а не в const char* или std::initializer_list<char>?ну вот про это и был вопрос. почему компилятор сначала ищет оператор= слева, а потом оператор string() справа, а не наоборот? т.е. с int, например, эта конструкция работает. Если бы компилятор поискал у моего класса оператор каста и нашёл бы его, всё собралось бы ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2019, 12:05 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMbПомог шаблонный оператор каста в ссылку на T.Это как? У меня не помогает. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2019, 13:43 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMba.guestА почему он должен генерить шаблон для каста в стринг а не в const char* или std::initializer_list<char>?ну вот про это и был вопрос. почему компилятор сначала ищет оператор= слева, а потом оператор string() справа, а не наоборот?Что значит "сначала" и "потом"? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2019, 13:54 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a.guestЭто как? У меня не помогает.там надо оба оператора в T и в T&. Я не знаю, почему, хорошо было бы, если бы кто-то объяснил :( a.guestЧто значит "сначала" и "потом"? ну вот как там идёт семантический разбор? Я не знаю. Находит выражение "=", потом смотрит, что слева и что справа? У меня в коде 2 варианта, получается 1. искать оператор = у string, который принимает на вход класс А (и не найти) 2. искать оператор string у класса А, чтобы он вернул строку, которая подходит для "=". где в стандарте написано, что компилятор идёт первым путём? потому что если я явно указываю каст в string - всё работает, т.е. компилятор идёт вторым путём. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 06:20 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
я тут пытаюсь опять сделать класс, который: 1. можно складывать в контейнеры 2. ему (переменным его типа) можно присваивать и считывать значения разных типов 3. и всё это без динамики и на момент компиляции. в бусте вроде есть типа Any, не знаю, насколько хорошо и удобно он решает задачу проблема универсальности в том, что когда мы создаём универсальный класс Param<T>, всё хорошо, до тех пор, пока нам не понадобится складывать его в контейнеры. Потому что контейнеры сразу накладывают ограничение на T. Отнаследовать Param<T> от интерфейса тоже не спасает, так как интерфейс должен иметь метод Get, который возвращает T. Таким образом, остаётся два варианта: 1. Не использовать шаблоны для Param 2. Написать свой контейнер (как мне кажется - вообще не вариант, потому что надо будет писать все контейнеры, всех итераторы и всё-всё) вариант 1 подразумевает, что само хранилище значений T должно быть как-то отделено от класса Param, при этом было нарезано компилятором, а не программистом. Мне пришла такая идея: шаблонный метод (назовём Data) со статической мапой внутри. Плюс пара шаблонных методов Set/Get, которые будут ходить в Data, передавая ключ, ссылку на объект и verb, что с этим объектом делать. Кроме того, Set и Get должны аккуратно срезать все модификаторы и ссылки с шаблонного параметра для Data, иначе тот наплодится на каждый тип (int, const int, const int&, int&& и так далее), а нам этого не нужно. Собственно, "всё хорошо" получилось. Бонусом (ненужным) получилось так, что в одном параметре можно хранить значения разных типов. Код: plaintext 1. 2. 3. 4. 5. 6.
Из чего, собственно, вытекает основная проблема: потеря информации о типе. Изначально я это стал делать для следующей задачи: - есть большое количество параметров разного типа у объектов - для объекта надо генерить UI для всех этих параметров (настройка и всё такое). Вручную рисовать UI под 50 параметров, где ещё всякие надписи и тултипы - не наш путь И ладно это был бы один класс, но классов много, у них у всех много параметров, и они требуют ещё сериализацию(sql-и пока пишутся вручную) и прочие обработки. Собственно, информация о типе как раз тут нужна, чтобы знать, какой UI для какого параметра генерить. Ну и отладка всего этого дела весьма сложна - данные все сидят внутри методов, их просто так не посмотришь. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 07:01 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMbВручную рисовать UI под 50 параметров, где ещё всякие надписи и тултипы - не наш путь два варианта альтернативных: 1. Именно проектирование руками в дизайнере по ГОСТ конкретной формочки. То есть проектирование. АРМ. 2. Обычно в ГУИ есть контрол типа вертикальный грид. Он по модели сам отображает разные типы в ГУИ. То есть в модели информации о типах и на VIEW просто отрисовка в строках или пикселях. Имхо ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 07:19 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMbпроблема универсальности в том, что когда мы создаём универсальный класс Param<T>, всё хорошо, до тех пор, пока нам не понадобится складывать его в контейнеры. Потому что контейнеры сразу накладывают ограничение на T. Отнаследовать Param<T> от интерфейса тоже не спасает, так как интерфейс должен иметь метод Get, который возвращает T. есть еще третий вариант - идиома Type Erasure . Если я правильно понял это именно то что вам нужно. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 08:20 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
CEMba.guestЭто как? У меня не помогает.там надо оба оператора в T и в T&. Я не знаю, почему, хорошо было бы, если бы кто-то объяснил :(Ты не удалил `operator string()`. А T& не при чём. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 09:35 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Cerebrumесть еще третий вариант - идиома Type Erasure .Не, она не подходит под третий пункт, определение всего на момент компиляции, потому что: HabrПочему RTTI нужно использовать к сожалению? Потому что, хотелось бы написать что-то вроде такого, чтобы перенести проверку типа в compile time: А у меня эта проверка делается в compile time. Так что я крут Не, на самом деле, я хорошо себе в голове представляю всю схему со статической типизацией и/или стиранием типа, какие есть архитектурные невозможности (к примеру, если Param не завязан никак на тип принимаемого параметра - это означает автоматом, что именно из Param обратно извлечь тип назад никак не удастся), и тут придётся как-то выбирать одно и отказываться от другого. Например, мне нужна информация о типе параметра для создания UI, я могу просто запоминать тип в отдельную переменную, потому что мне потом будет проще написать функцию разбора списка параметров, основанную на switch-case-ах, чем на шаблонных проверках типа, к тому сам список не имеет отношения к шаблонам. Про отказ-выбор. Это, так-то, уже второй мой вариант решения избавления от типов в контейнерах. Первый на предыдущей странице, там как раз попытка написать свой "контейнер". И там можно по имени/ключу из контейнера достать параметр, который имеет информацию о своём типе. А можно сразу значение по ключу. Но у той реализации есть свои проблемы, она автоматически сортирует все параметры(рекурсивный шаблон в основе). Она в основе имеет конкретный stl-ный контейнер, если нужно другой - нужно новую реализацию. Она требует в объявлении указать, какие типы будут использованы. У неё нету итераторов по всей коллекции, но можно сделать итераторы по типам(и мне этого хватает там, где оно применяется), и они опять же привязаны жёстко к своим типам. Но как статическая-"динамическая" типизация, вышло неплохо, ящетаю ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 09:55 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a.guestТы не удалил `operator string()`. А T& не при чём.ну это в этом примере, а в рабочем коде у меня два шаблонных каста в T и в T&, без них не компилируется :( ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2019, 10:05 |
|
|
start [/forum/topic.php?fid=57&msg=39815316&tid=2017587]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
37ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
49ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 141ms |
0 / 0 |