Название: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 08:19 Добрый день
Пример: есть такой темплейт Код Хорошо, теперь я могу его использовать для любых контейнеров с прямым доступом (std::vector, QVector, QList). Но вот мне понадобилось напр так Код Из-за разницы в обращении к эл-ту приходится переписывать. Ну или чуть более сложный случай - напр "x" в координатах заданного виджета (а не парента). Основания для обобщения вроде имеются, но как это лучше сделать? Спасибо Название: Re: Контейнер из подручных средств Отправлено: kuzulis от Июнь 03, 2016, 08:28 http://ru.cppreference.com/w/cpp/algorithm/max_element не?
Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 09:18 http://ru.cppreference.com/w/cpp/algorithm/max_element не? Ну вот, как говорит мой свояк, "абы фатануть" :) Только ради вычисления максимума нет смысла заморачиваться, это чисто для примера.Название: Re: Контейнер из подручных средств Отправлено: Old от Июнь 03, 2016, 10:59 Ну вот, как говорит мой свояк, "абы фатануть" :) Только ради вычисления максимума нет смысла заморачиваться, это чисто для примера. Ну пример kuzulis еще намекает на функторы. Вы можете вынести код возвращающий значение (эдакий геттер) для сравнения за шаблон. В случае с контейнером чисел, геттер будет просто возвращать число из коллекции, а в случае виджета или QPoint - значение нужной величины (в вашем случае значение x).Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 11:07 Ну пример kuzulis еще намекает на функторы. Вы можете вынести код возвращающий значение (эдакий геттер) для сравнения за шаблон. В случае с контейнером чисел, геттер будет просто возвращать число из коллекции, а в случае виджета или QPoint - значение нужной величины (в вашем случае значение x). Не хотелось бы "эдакий", т.к. его придется обеспечивать и для всех банальных контейнеров.Да, а где же наш энтузиаст шаблонной магии? :) Название: Re: Контейнер из подручных средств Отправлено: GreatSnake от Июнь 03, 2016, 11:18 Не хотелось бы "эдакий", т.к. его придется обеспечивать и для всех банальных контейнеров. Вместо функтора для getter-a можно задействовать опциональную std::function.Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 11:30 Вместо функтора для getter-a можно задействовать опциональную std::function. А можно пример как это будет выглядеть в данном случае? (std::function пока в мой арсенал не входит, все не переползем на С++ 11)И еще могут понадобиться доп данные для чтения/записи эл-та (см пример с "х" в координатах заданного виджета) Название: Re: Контейнер из подручных средств Отправлено: Old от Июнь 03, 2016, 11:34 Не хотелось бы "эдакий", т.к. его придется обеспечивать и для всех банальных контейнеров. Лямбды это упростят:Код
Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 13:20 Лямбды это упростят: Так-то оно так, но вот есть десяток ф-ций наподобие GetMaxNegative - и каждую придется "одевать", непрахтишно. Да и передача хвунктора как-то не очень. Нельзя ли сосредоточить весь новый код в том что "подается на вход GetMaxNegative" ?Название: Re: Контейнер из подручных средств Отправлено: Old от Июнь 03, 2016, 13:22 Нельзя ли сосредоточить весь новый код в том что "подается на вход GetMaxNegative" ? На вход подается коллекция QPoint, по какой оси должен искаться максимум? А если коллекция QColor?Название: Re: Контейнер из подручных средств Отправлено: Racheengel от Июнь 03, 2016, 14:40 Стремиться, имхо, надо к следующему:
Код
Таким образом через параметры можно передать и вектор, и функтор для доступа к нему (если базовый не подходит). Название: Re: Контейнер из подручных средств Отправлено: kambala от Июнь 03, 2016, 15:19 Лямбды это упростят: Так-то оно так, но вот есть десяток ф-ций наподобие GetMaxNegative - и каждую придется "одевать", непрахтишно. Да и передача хвунктора как-то не очень. Нельзя ли сосредоточить весь новый код в том что "подается на вход GetMaxNegative" ?Название: Re: Контейнер из подручных средств Отправлено: m_ax от Июнь 03, 2016, 15:46 Можно специализировать getter_helper под различные пользоваткльские типы и дёргать его из функции:
Код
Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 15:57 такое вообще бывает в нединамических языках? (ну кроме switch-enum подхода) Не понял, что "бывает"? В смысле десятки ф-ций работающих с одним контейнером? Да, конечноНазвание: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 16:11 Можно специализировать getter_helper под различные пользоваткльские типы и дёргать его из функции: Так мне кажется логичнее, но зачем нам засорять код рабочих ф-ций каким-то getter_helper'ом ? Почему не такКод Вот правда не знаю как сделать запись, чтобы [] возвращал ссылку на int (ее ведь "в оригинале" может не быть) Название: Re: Контейнер из подручных средств Отправлено: Old от Июнь 03, 2016, 16:25 Можно специализировать getter_helper под различные пользоваткльские типы и дёргать его из функции: Знаете что не нравиться: для каждого типа может быть только один хелпер. Например, для QPoint нельзя в одном случае считать по x, а в другом по y.Название: Re: Контейнер из подручных средств Отправлено: kambala от Июнь 03, 2016, 16:42 такое вообще бывает в нединамических языках? (ну кроме switch-enum подхода) Не понял, что "бывает"? В смысле десятки ф-ций работающих с одним контейнером? Да, конечноЦитировать сосредоточить весь новый код в том что "подается на вход GetMaxNegative" в objc с его «магией рантайма» я еще могу представить как это сделать, но в ++... вариант с лямбдами/функторами кажется вполне естественным.Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 03, 2016, 17:31 ... вариант с лямбдами/функторами кажется вполне естественным. Пока одна содержательная/рабочая ф-ция - все хорошо. Код
Код А как только объявится еще "виртуальный контейнер" (хотя бы "y" вместо "x") - опять все для КАЖДОЙ в objc с его «магией рантайма» я еще могу представить как это сделать, но в ++... Шо за пессимизм? :)Стремиться, имхо, надо к следующему: Не вкурил, можно подробнее? Как (или куда) пристраивать написанное?Код
Таким образом через параметры можно передать и вектор, и функтор для доступа к нему (если базовый не подходит). Название: Re: Контейнер из подручных средств Отправлено: kambala от Июнь 03, 2016, 18:38 ну так идентичные лямбды делаются обычными функциями.
а если передавать в качестве параметра GetMaxNegative() еще и указатель на метод элемента контейнера? Название: Re: Контейнер из подручных средств Отправлено: m_ax от Июнь 03, 2016, 19:24 Цитировать Так мне кажется логичнее, но зачем нам засорять код рабочих ф-ций каким-то getter_helper'ом ? Почему не так Ну так Вы же сами в первом посте потавили так вопрос. В любом случае где-то придётся руками прописывать поведение для конкретного типа. Здесь мы функцию зато не трогаем больше. Цитировать Знаете что не нравиться: для каждого типа может быть только один хелпер. Например, для QPoint нельзя в одном случае считать по x, а в другом по y. Согласен) Можно ещё один шаблон добавить, который уже ракзличные стратегии определяет для данного типа.. Хотя я бы с лямбдами сделал и не запаривался) Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 04, 2016, 11:40 ну так идентичные лямбды делаются обычными функциями. Конечно можно, но это отягощает рабочие ф-ции. Два темплейт-аргумента вместо одного, плюс "default" реализация, плюс лямбды и/или функторы повсеместно. Когда ф-ций много это становится очень ощутимым.а если передавать в качестве параметра GetMaxNegative() еще и указатель на метод элемента контейнера? Ну так Вы же сами в первом посте потавили так вопрос. В любом случае где-то придётся руками прописывать поведение для конкретного типа. В исходном примере возвращаемое значение int (конкретный тип), т.е. меня не интересует что-то другое, нет планов адаптировать под double или еще что.Вопрос был в том что исходные (хранимые) значения сами могут и не находиться в классе-контейнере, но для них существует ф-ционал: - счетчик (число эл-тов) - доступ к значению по индексу Ну как бы "виртуальный контейнер" прямого доступа Название: Re: Контейнер из подручных средств Отправлено: Racheengel от Июнь 04, 2016, 14:47 Не вкурил, можно подробнее? Как (или куда) пристраивать написанное? Вторым параметром при необходимости (F* fvec): template <class T, class F = GetVectorValue> int GetMaxNegative( const T & vec, F* fvec ) Примерно как: GetMaxNegative(myVector, myFVector); myFVector должен быть, соответвенно, заточен на обработку myVector. Каждый раз для получения index элемента вектора будет вызвано myFVector ->GetVectorValue(myVector, index); Название: Re: Контейнер из подручных средств Отправлено: Igors от Июнь 04, 2016, 15:17 Вторым параметром при необходимости (F* fvec): Понял, спасибо. Это близко к предложенным вариантам, но кажется мне поудобнее. Все же "вживление" специального геттера... Ведь следом за ним неизбежно последует сеттер. Зачем мы таким образом достигаем ф-ционала оператора [], не лучше ли перекрывать его если требуется ? template <class T, class F = GetVectorValue> int GetMaxNegative( const T & vec, F* fvec ) Название: Re: Контейнер из подручных средств Отправлено: Racheengel от Июнь 04, 2016, 18:53 Ну а как без геттера? Ведь вектор уже имеет собственный оператор [], речь о том, чтобы специализировать "результат" оператора [].
Например, vec.x(), или vec.y() и т.д. - тут надо ж как-то явно указывать, что именно вам нужно. Название: Re: Контейнер из подручных средств Отправлено: m_ax от Июнь 04, 2016, 21:33 Цитировать Вопрос был в том что исходные (хранимые) значения сами могут и не находиться в классе-контейнере, но для них существует ф-ционал: Т.е. предлагаете свой враппер писать под контейнер? Не совсем понимаю, чем это лучше специализации для геттера? В подходе с геттером гибкости больше: появилась потребность обращаться, например к point.y() - написали отдельную специализацию и т.д.. И от типа контейнера можно абстрогироваться (не обязательно по индексу обращаться к элементу).. - счетчик (число эл-тов) - доступ к значению по индексу Ну как бы "виртуальный контейнер" прямого доступа |