Название: Про templat Отправлено: Ced от Май 06, 2017, 11:54 Коллеги, подскажите можно ли иметь шаблонный метод в классе, который не является template?
Название: Re: Про templat Отправлено: ViTech от Май 06, 2017, 12:52 Можно.
Название: Re: Про templat Отправлено: Igors от Май 06, 2017, 13:06 [off]Ну вот, началось пагубное увлечение. "Коготок увяз - всей птичке пропасть" :'([/off]
Название: Re: Про templat Отправлено: Ced от Май 06, 2017, 19:35 [off]Ну вот, началось пагубное увлечение. "Коготок увяз - всей птичке пропасть" :'([/off] Я заметил. Но задача реально того требует. Название: Re: Про templat Отправлено: Ced от Май 06, 2017, 22:16 Можно. Спасибо. Еще вопрос. Имеется вот такая конструкция Код: template <typename T>class X : public Y Могу ли я определить значение Т в ходе выполнения конструктора Y? Или может можно сделать иначе, так, чтобы сперва создать объект Y, а после выбрать значение Т? Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 11:28 Что то я не пойму
Код: template <typename T>class Parametr : public ParametrName И в итоге: Код: ошибка: undefined reference to `Parametr<float>::Parametr()' Что не так? Название: Re: Про templat Отправлено: Igors от Май 07, 2017, 13:00 Могу ли я определить значение Т в ходе выполнения конструктора Y? Нет. Темплаты - они как бы "статики", т.е. все известно и решается на этапе компиляции, никаких "динамических" манипуляций с типом нет. Или может можно сделать иначе, так, чтобы сперва создать объект Y, а после выбрать значение Т? Что то я не пойму Код
Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 13:08 Код
Попробовал. Результат тот же. Компилятор не желает видеть, что у класса Parametr есть такой конструктор. Но вообще это тестовый пример. Я все упростил от безысходности. Бьюсь, как в стенку. А задумка в целом такова: Есть шаблонный класс. Хочу создать вектор ссылок на объекты этого класса. За тем определить длину вектора. Для каждого элемента вектора динамически создать объект. У каждого объекта свое значение параметра Т. Это возможно? Название: Re: Про templat Отправлено: Igors от Май 07, 2017, 13:40 Попробовал. Результат тот же. Компилятор не желает видеть, что у класса Parametr есть такой конструктор. Учтите что тело конструктора должно находиться в той же "единице трансляции"Но вообще это тестовый пример. Тем лучше, выкладывайте его как zip с компилируемым примером внутри А задумка в целом такова: Да, это довольно популярная задача, только "вектор ссылок" вряд ли, наверное имелся ввиду "вектор указателей". Пишете базовый класс, от него наследуете темплейт класс (как Вы и начали делать) и работаете через виртуалы базового класса. Есть шаблонный класс. Хочу создать вектор ссылок на объекты этого класса. За тем определить длину вектора. Для каждого элемента вектора динамически создать объект. У каждого объекта свое значение параметра Т. Это возможно? Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 13:49 Цитировать Учтите что тело конструктора должно находиться в той же "единице трансляции" Расположение таково: Класс Parametr находится в файле Parametrs.h Конструктор - в файле Parametrs.cpp Объект *x пытаюсь создавать в файле MyServer.cpp как локальную переменную в конструкторе класса MyServer. Все в одном проекте. Компилятор не ругается на объявление Parametr<float> *x и стало быть класс Parametr он видит. А вот наличие в нем конструктора не желает признавать. Я сперва пользовался другим конструктором с параметрами. Потом решил исключить все возможные причины ошибки и создал кнструктор предельно простой. Это не помогло. Раз задуманная мною схема реализуема, значит с этой проблемой надо разобраться. Посоветуйте пожалуйста, в чем все же ошибка? Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 14:15 Цитировать Учтите что тело конструктора должно находиться в той же "единице трансляции" До меня дошло наконец. Спасибо. Это для шаблонов такая особенность?И как же быть? Описывать конструктор непосредственно в теле класса? Или как это принято решать? Про это где-то написано? Название: Re: Про templat Отправлено: Igors от Май 07, 2017, 14:28 Дошло наконец. Спасибо. Это для шаблонов такая особенность? Да, в момент "инстанциации" все тела должны быть видимыИ как же быть? Описывать конструктор непосредственно в теле класса? Можно и так, это несколько "замусоривает" хедер, но - дело вкуса. Я обычно сваливаю тела в файлнапр "MyClass_Templates.cpp", который включаю НЕ в проект, а в хедер Код
[off] Но задача реально того требует. Увлечение этой заразой сгубило немало хороших ребят [/off] Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 14:35 Спасибо огромное. Бился с этим три дня непрерывно. Нигде не смог прочитать. С этим понятно. Помогите пожалуйста еще с вектором.
Я предполагаю объявить его так Код: template <typename T> class X Это корректно? Название: Re: Про templat Отправлено: Igors от Май 07, 2017, 15:47 Я предполагаю объявить его так Нет. Код: template <typename T> class X Это корректно? Код Это уже не объявление а инстациирование, здесь может быть только конкретный тип, напр float. но никак не typename. Правильно напр так Код В контейнере могут быть только эл-ты одного типа, поэтому придется там хранить указатели на базовый класс, напр BaseElement. И опять Вы допускаете ту же ошибку - обращение к массиву векторов вместо обращения к эл-ту вектора Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 15:50 Спасибо. Сняли с меня огромную головную боль. Раньше никогда с шаблонами не работал. Очень помогли.
Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 19:28 Еще раз прошу подсказки. Как можно внутри конструктора шаблона узнать, какой тип данных подан на вход?
Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 21:48 Например так
Код
Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 21:52 Igors,
Лучше не указывать void при отсутствии параметров в объявлении метода, функции. 1. Это pure c style 2. Это дезориентирует новичков. Я знаю людей, которые свято верят, что в относительно старых версиях gcc без void в скобках код не скомпилируется. Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 21:53 Например так Код
Честно сказать, я не понял, как это работает. Может поясните? Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:04 Есть шаблонный класс, который хранит в себе value_ типа T.
Тип T задаётся пользователем шаблона например так Код В примере шаблон инстанцируется типом int, конструктор принимает int конвертируя double по всем канонам :) Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:08 Можно конкретнее, что именно за задача стоит. Вдруг шаблоны и не нужны...
Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 22:09 Есть шаблонный класс, который хранит в себе value_ типа T. Тип T задаётся пользователем шаблона например так Код В примере шаблон инстанцируется типом int, конструктор принимает int конвертируя double по всем канонам :) Или я Вас опять не понял, или плохо объяснил, чего хочу. Проблема вот в чем: Некоторые операции не могут быть реализованы одинаково для различных типов данных. Это очевидно. В конструкторе класса я совершаю с данными такие операции. Чтобы корректно обрабатывать различные типы, я хочу знать, каким типом инстанцирован тот конкретный объект, для которого сейчас запущен конструктор. Мне кажется, Ваш код эту проблему не решает. Мне нужно получить информацию об инстанцирующем типе в виде признака. по которому можно организовать ветвление алгоритма. Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 22:12 Можно конкретнее, что именно за задача стоит. Вдруг шаблоны и не нужны... Обрабатывается поток данных. Данные поступают в виде строк. Каждая строка содержит набор значений. Значения эти могут быть разного типа и наперед их типы не известны. Для описания структуры потока используется специальный файл. Из него можно считать, что придет в потоке. При каждой обработке этот файл может быть различным. Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:24 Задачей не проникся.
Для определения типа: Можно воспользоваться в крайнем случае http://www.cplusplus.com/reference/type_traits/ Можно немножко усложнить шаблон путем специализации Код
Код
Код и т.д. специализируем все необходимые нам обработки теперь сам шаблон Код
инстанцируем так: Код
Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:28 К слову, шаблоны - инструмент времени компиляции.
А чтение потоков и файлов происходит во время выполнения программы. Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:31 Предлагаю подробнее разжевать задачу. Привести 2-3 примера, того что приходит в потоке данных и как при описании структуры используется файл (пример что он содержит).
Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 22:34 Для задачи я нашел решение. Оно конечно не универсально, но в моем случае вполне пригодно. Теперь интересуюсь уже из любопытства, есть ли что-то менее костыльное. Предложенные Вами способы честно говоря не очень порадовали. По ссылке описана возможность для многих типов, но я скажем не нашел там варианта узнать про тип bool. Второй способ таков, что можно и не пользоваться шаблонами. Просто ветвим алгоритм для каждого типа и все. Сейчас у меня есть ветвление при инстанцировании. Я считываю файл настроек, узнаю о типе каждого параметра и инстанцирую соответствующий класс в нужной ветке. Дальше все вроде красиво.
Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 22:39 Предлагаю подробнее разжевать задачу. Привести 2-3 примера, того что приходит в потоке данных и как при описании структуры используется файл (пример что он содержит). Вот пример такого файла, если интересноКод: [Parametr] А вот код, который его читает: Код: QTextStream *in1 = new QTextStream(parametrsFile); Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:48 Ну, вроде, это единственный вариант делать именно то, что вы делаете.
Единственное, что могу предложить, это только сделать мапу данных и указателей на функцию типа: Код
Код
Поведение конструктора Param описать с помощью Traits, как было написано выше. Вызывать так Код
Название: Re: Про templat Отправлено: Ced от Май 07, 2017, 22:51 Ну, вроде, это единственный вариант делать именно то, что вы делаете. Единственное, что могу предложить, это только сделать мапу данных и указателей на функцию типа: Код
Код
Поведение конструктора Param описать с помощью Traits, как было написано выше. Вызывать так Код
Спасибо. Это намотаю на ус. Думаю, пригодится, когда буду рефакторить эту писанину. Сейчас просто времени очень мало. Приходится лепить с листа. Качество кода меня лично удручает, но такими темпами я лучше не способен. Очень надеюсь, что будет возможность потом все это причесать. Название: Re: Про templat Отправлено: __Heaven__ от Май 07, 2017, 22:53 Имхо, xml структура для такого файла здесь уместнее.
Ладно, удачи. Название: Re: Про templat Отправлено: Igors от Май 08, 2017, 11:45 Спасибо. Это намотаю на ус. Думаю, пригодится, когда буду рефакторить эту писанину. Сейчас просто времени очень мало. Приходится лепить с листа. Качество кода меня лично удручает, но такими темпами я лучше не способен. Очень надеюсь, что будет возможность потом все это причесать. Весьма слабые угрызения совести :) Вот пример такого файла, если интересно Ага, ну я так и знал, Вы совершенно напрасно связались с темплейтами, здесь прямо-таки напрашивается QVariant. Или др реализация variant, возможно даже на темплейтах но уже делающая много черновой работы которую сейчас Вам нужно реализовывать самомуНазвание: Re: Про templat Отправлено: Ced от Май 08, 2017, 11:51 Цитировать Ага, ну я так и знал, Вы совершенно напрасно связались с темплейтами, здесь прямо-таки напрашивается QVariant. Или др реализация variant, возможно даже на темплейтах но уже делающая много черновой работы которую сейчас Вам нужно реализовывать самому Не сомневаюсь, что мною выбран не лучший вариант реализации. Причина в следующем: С шаблонами я раньше не работал, но понимаю, что это такое. Про QVariant я пока не знаю ничего. Времени на изучение сейчас у меня нет. Я рассчитываю сделать вариант "на коленке", а после получить время на рефакторинг. Некоторые ошибки в коде я делаю намеренно, чтобы у заказчика не было возможности сказать "Работает и ладно". Смешно? - Думаю, не всем. В такой ситуации работают многие программисты. Не многие решаются попытаться ее изменить. Я решил попробовать. Название: Re: Про templat Отправлено: Igors от Май 08, 2017, 12:40 Не сомневаюсь, что мною выбран не лучший вариант реализации. Причина в следующем: С шаблонами я раньше не работал, но понимаю, что это такое. Про QVariant я пока не знаю ничего. Времени на изучение сейчас у меня нет. А вот время на эксперименты с темплейтами нашлось, по Вашим же словам бились 3 дня. Собственно в этом их опасность и есть. Вещь сама по себе неплохая, иногда даже необходимая. Но очень часто она увлекает программиста в мифический мир обобщений. Масса времени уходит на то как же пристроить всякие "хитросплетения". Наконец все получилось, ура! Пройдет эдак полгода, глянешь опять этот код - ничего хорошего, иной раз и сам забыл что хотел.Я рассчитываю сделать вариант "на коленке", а после получить время на рефакторинг. Некоторые ошибки в коде я делаю намеренно, чтобы у заказчика не было возможности сказать "Работает и ладно". Смешно? - Думаю, не всем. В такой ситуации работают многие программисты. Не многие решаются попытаться ее изменить. Я решил попробовать. А в чем заключается Ваше (мужественное) решение изменить? Пока ни в чем, просто тешите себя надеждами. Жизнь покажет..Название: Re: Про templat Отправлено: Ced от Май 08, 2017, 12:49 Согласен. Жизнь покажет:)
Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 01:09 И снова я к Вам с вопросом
Код
Реализовал такую схему. А как теперь через элементы QVector добраться до свойств или методов объектов класса Х? Я из не вижу. Название: Re: Про templat Отправлено: Igors от Май 09, 2017, 04:49 Реализовал такую схему. А как теперь через элементы QVector добраться до свойств или методов объектов класса Х? А какие методы (зависящие от темплейт типа) нужны? Не хочу показаться навязчивым, но если время поджимает то лучше соскочить на QVariant, выглядит примерно такКод Заметьте как стало "приятнее". Можно спокойно копировать как сам theParamList, так и его элементы. А в варианте с темплейт для этого нужно приложить усилия. Или хотите все-таки "помучить котов"? :) Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 12:01 А какие методы (зависящие от темплейт типа) нужны? [/quote]
Код: class ParametrName Нужен доступ к Код: MyQueueBuffer<T> *buffer, T minPossibleValue; Название: Re: Про templat Отправлено: Igors от Май 09, 2017, 13:25 Нужен доступ к Т.е. к тому что разрисовали геттерами/сеттерами. Объявляете чистый виртуал в базовом классе, напрКод И реализуете его в template наследнике Код Если понадобится выписываете частичную специализацию Название: Re: Про templat Отправлено: Old от Май 09, 2017, 13:35 Объявляете чистый виртуал в базовом классе, напр А какой смысл в этом виртуале? Для чего его переопределять в потомке (шаблоне!), если все равно типы максимума/минимума всегда ограничены double? Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 13:38 Объявляете чистый виртуал в базовом классе, напр А какой смысл в этом виртуале? Для чего его переопределять в потомке (шаблоне!), если все равно типы максимума/минимума все равно ограничены double? А что меняется от типа? Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 13:39 Нужен доступ к Т.е. к тому что разрисовали геттерами/сеттерами. Объявляете чистый виртуал в базовом классе, напрКод И реализуете его в template наследнике Код Если понадобится выписываете частичную специализацию Значит мне под каждый возможный тип определять отдельную виртуальную функцию? Название: Re: Про templat Отправлено: Old от Май 09, 2017, 13:40 А что меняется от типа? Не знаю, что у вас меняется от типа? Для чего-то вы шаблон завели? :)Название: Re: Про templat Отправлено: Old от Май 09, 2017, 13:42 Значит мне под каждый возможный тип определять отдельную виртуальную функцию? Это если вы ходите сделать максимально плохо. Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 13:44 А что меняется от типа? Не знаю, что у вас меняется от типа? Для чего-то вы шаблон завели? :)Я вот в каком смысле: Что значит "...ограничены double"? Имеется ввиду, он самый длинный из используемых? или что-то иное? Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 13:48 Значит мне под каждый возможный тип определять отдельную виртуальную функцию? Это если вы ходите сделать максимально плохо. А если не максимально? Название: Re: Про templat Отправлено: Old от Май 09, 2017, 13:58 А если не максимально? Например так. Есть базовый класс ParametrBase, от него наследуются остальные четыре:ParametrContinuous ParametrDiscreteYesNo ParametrTime ParametrDateTime У каждого класса будут свои специфичные данные и методы. У ParametrContinuous будут описаны минимумы и максимумы, которые не нужны для других типов, у ParametrTime будут методы для хранения времени и т.д. А в базовый класс стоит выносить только общие методы, например метод toString, который переопределяется в наследниках и правильно формирует значение параметра в строку для дальнейшего отображения. Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 14:01 А если не максимально? Например так. Есть базовый класс ParametrBase, от него наследуются остальные четыре:ParametrContinuous ParametrDiscreteYesNo ParametrTime ParametrDateTime У каждого класса будут свои специфичные данные и методы. У ParametrContinuous будут описаны минимумы и максимумы, которые не нужны для других типов, у ParametrTime будут методы для хранения времени и т.д. А в базовый класс стоит выносить только общие методы, например метод toString, который переопределяется в наследниках и правильно формирует значение параметра в строку для дальнейшего отображения. Тогда чего шаблон? Я бы под каждый тип данных определить класс и не ломать голову. Название: Re: Про templat Отправлено: Old от Май 09, 2017, 14:06 Тогда чего шаблон? Я бы под каждый тип данных определить класс и не ломать голову. Вот тип параметра ParametrContinuous имело бы смысл сделать шаблоном, если в программе возможны разные типы параметров (целые/реальные).Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 14:17 В итоге решил так:
Код: template <typename T> class MyQueueBuffer Проверил. Работает. Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 14:21 И еще. Работа - работой, но всех с праздником Победы!
Название: Re: Про templat Отправлено: Igors от Май 09, 2017, 14:45 Код: int getType (); В итоге решил так: Не понял что решилось :) Значит мне под каждый возможный тип определять отдельную виртуальную функцию? Нет, так их просто нельзя будет затем использовать, т.к. виртуалы могут иметь только конкретные типы аргументов и возвращаемых значений. Виртуалы нужны чтобы рулить этой "оравой" разно-типных наследников. Напр пробегаться по контейнеру указателей на базовый тип и однообразно вызывать getMinPossibleValue, не влезая в утомительные разборки какой там тип конкретно.И еще. Работа - работой, но всех с праздником Победы! Да, спасибо, и Вас тоже. Хороший праздник!Название: Re: Про templat Отправлено: Ced от Май 09, 2017, 14:50 Цитировать Не понял что решилось :) Да так и решилось. Наделал виртуалов и сделал функции, возвращающие сылки на массивы. содержащие шаблоны. А работать с этими ссылками буду в обработчиках. которые знают тип данных, с которым работают. Название: Re: Про templat Отправлено: Ced от Май 10, 2017, 21:33 [/quote]Ага, ну я так и знал, Вы совершенно напрасно связались с темплейтами, здесь прямо-таки напрашивается QVariant. Или др реализация variant, возможно даже на темплейтах но уже делающая много черновой работы которую сейчас Вам нужно реализовывать самому [/quote] Все, сдаюсь. Переделываю на QVariant. C этими шаблонами легче застрелиться. Название: Re: Про templat Отправлено: ViTech от Май 11, 2017, 12:46 Все, сдаюсь. Переделываю на QVariant. C этими шаблонами легче застрелиться. Стреляться из-за шаблонов не стоит. Надо лучше изучить их, хотя бы основы, и применять по назначению :). Название: Re: Про templat Отправлено: Ced от Май 12, 2017, 15:21 Стреляться из-за шаблонов не стоит. Надо лучше изучить их, хотя бы основы, и применять по назначению :). Вероятно с назначением я в этот раз промахнулся. Ну за то изучил основы:) |