LINUX.ORG.RU

STL. Как оптимальнее сделать предикат с каким-то еще необходимыми параметрами


0

1

Есть выполнение функции find_if с предикатом pr

bool pr(DrawObjects* obj)
{
	return obj->isNormal();
}
...
i_objects = find_if(m_objects.begin(), m_objects.end(), pr);
...

как оптимальнее сделать так, чтобы в предикат передать какие-то еще параметры:

bool pr(DrawObjects* obj, int l, int h)
{
	return obj->isNormal(l, h);
}

и возможно ли это?


Сделать предикат классом с методом ()

slav ★★
()

[code] class pr:public std::unary_function<DrawObjects*, int> { int l; int h; public: pr(int l_, h_) : l(l_),h(h_){} int operator()(DrawObjects* arg) const { return arg->isNormal(l, h); } }

// использование

i_objects = find_if(m_objects.begin(), m_objects.end(), pr(L,H) );

[/code]

nikitos ★★★
()
Ответ на: комментарий от nikitos

спасибо огромное, сейчас буду разбираться, но более менее понятно

g-71
() автор топика

А ещё можно использовать bind.

const86 ★★★★★
()
Ответ на: комментарий от Begemoth

Да что все так привязались к этому сборищу велосипедов под названием boost? В STL есть своя реализация bind: bind1st и bind2nd. Для простых случаев этого вполне достаточно, а для более сложных реализаций лучше использовать функциональные объекты как показал nikitos

Torvus
()
Ответ на: комментарий от Torvus

Для простых случаев этого вполне достаточно

Ну покажи как bind1st или bind2nd в данном случае использовать. Не нравиться boost::bind в C++0x есть std::bind и лямбда-выражения.

Begemoth ★★★★★
()
Ответ на: комментарий от Reset

> и что, Qt уже может заменить лисп ? :)

лисп настолько «часто» используется, что его может заменить все что угодно ;)

aho
()
Ответ на: комментарий от Begemoth

я бы сделал так:

class pr : public std::binary_function<DrawObjects*, int, int>
{
  int operator()( DrawObjects *arg1, int arg2 ) const
  {
    return arg1->isNormal( arg2 );
  }
};

i_objects = find_if( m_objects.begin(), m_objects.end(), std::bind2nd( pr(), h ) );
Для большего количества параметров нужно сделать конструктор класса pr (этот вариант уже был показан выше)

Torvus
()
Ответ на: комментарий от Torvus

У отдельных классов для функциональных объектов, помимо очевидного плюса - ясности кода, есть в ряде случаев существенный минус - отдалённость определения от точки использования. Это не есть хорошо в случае единственного использования этого класса. Приведённый тобой пример использования ИМХО менее читабелен, чем вариант с boost::bind в данном случае. Отдельный класс для функционального объекта я бы стал использовать если бы в выражении были бы вложенные вызовы, условия (boost::lambda это кошмар).

Begemoth ★★★★★
()
Ответ на: комментарий от annulen

лишняя зависимость

Скопируй boost::bind в исходники проекта.

Begemoth ★★★★★
()
Ответ на: комментарий от annulen

Она в хидерах. И вообще это Си++, а тут без буста довольно проблематично писать что-либо серьезное.

Reset ★★★★★
()
Ответ на: комментарий от Reset

И вообще это Си++, а тут без буста довольно проблематично писать что-либо серьезное.

Да что вы говорите! Лично я последние 3,5 года программистской деятельности прекрасно обхожусь без этих велосипедов. P.S. Конечно, это мое ИМХО

Torvus
()
Ответ на: комментарий от Torvus

значит ты тратишь кучу времени на написание, тестирование и сопровождение своих собственных велосипедов

Reset ★★★★★
()
Ответ на: комментарий от Begemoth

В данном случае я с вами полностью согласен. Просто лично я считаю неоправданной роскошью ради такой мелочи тянуть в зависимости монструозный boost. Хотя, если он используется по всему проекту, то boost::bind вам в руки

Torvus
()
Ответ на: комментарий от Torvus

> Просто лично я считаю неоправданной роскошью ради такой мелочи тянуть в зависимости монструозный boost.

В boost для Вашей задачи самое прямое и правильное решение — каррирование. Создание функционального объекта это уже другая вещь — замыкание.

annoynimous ★★★★★
()
Ответ на: комментарий от Reset

значит ты тратишь кучу времени на написание, тестирование и сопровождение своих собственных велосипедов

Тут вы глубоко заблуждаетесь. Да, не спорю, бывали моменты, когда было бы проще использовать boost, но, хорошенько поразмыслив, каждый раз находился более простой и очевидный путь

Torvus
()
Ответ на: комментарий от annoynimous

...для Вашей задачи...

Ну начнем с того что задача не моя

Torvus
()
Ответ на: комментарий от Torvus

Я не заблуждаюсь. Мой опыт говорит мне прямо противоположное. Если не использовать буст, то получается нагромождение велосипедов, да еще и с кучей ifdef'ов, если речь идет о кроссплатформенной разработке. Мне тоже не нравится буст, но, увы, в C++ без него очень сложно.

Reset ★★★★★
()
Ответ на: комментарий от Reset

Подобного рода классы пишутся и тестируются за пару минут. И иногда просто невозможно использовать boost или выдирать файлы из него.

Booster ★★
()
Ответ на: комментарий от Torvus

Под мелочью вы понимаете boost::bind или единичное использование? Если bind, то повторюсь - его можно скопировать в дерево исходников, man bcp за подробностями.

Begemoth ★★★★★
()
Ответ на: комментарий от Booster

ну во-первых не за пару минут, а во-вторых кроме bind'а есть еще туева хуча вещей которые нужны постоянно

Reset ★★★★★
()
Ответ на: комментарий от Begemoth

Под мелочью вы понимаете boost::bind или единичное использование

Единичное использование

его можно скопировать в дерево исходников

А вы сами хоть раз пытались такое провернуть? Попробуйте и получите незабываемые впечатления от прохождения этого квеста. Boost до ужаса запутан и завязан сам на себе, и нет никаких гарантий, что boost::bind не использует что-нибудь типа boost::lambda или что-то вроде того.

Torvus
()
Ответ на: комментарий от Reset

кроме bind'а есть еще туева хуча вещей которые нужны постоянно

Приведите пример. Может, мне просто не попадались задачи, которые без boost'а не решаются?

Torvus
()
Ответ на: комментарий от Reset

thread

pthread

smart_ptr

Включить мозг при использовании указателей

interprocess

sendmsg, signal и т.п.

filesystem, asio

Даже не знаю что там такого, чего может постоянно не хватать...

lexical_cast и прочие строковые функции

stringstream

Torvus
()
Ответ на: комментарий от Torvus

pthread

А на альтернативной ОС?

Включить мозг при использовании указателей

Даже не смешно.

Даже не знаю что там такого, чего может постоянно не хватать...

А в стандартной библиотеке уже появились средства манипулирования путями файлов, получения информации о файлах?

stringstream

Опять не смешно. Можно выражение с использованием stringstream эквивалентное boost::lexical_cast<foo>(s)?

Далее добавлю полезную мелочь boost/cstdint.hpp и не мелочь boost::optional и boost::variant.

Begemoth ★★★★★
()
Ответ на: комментарий от Torvus

pthread

А на кроссплатформенность забиваем? А для того, чтобы пустить в отдельный поток метод класса будем городить свой boost::bind.

Включить мозг при использовании указателей

В больших проектах такой подход плохо работает.

sendmsg, signal и т.п.

см. пункт 1

stringstream

== городить собственные велосипеды, а потом получается, что каждый пишет собственный велосипед вместо того, чтобы использовать стандратные средства и проект обрастает Си++ мхом.

В общем, по всему вышесказанному могу сделать вывод, что опыта промышленного программирования у тебя маловато.

Reset ★★★★★
()
Ответ на: комментарий от Begemoth

А на альтернативной ОС?

Нет других ОС, кроме Linux. А если серьезнее, то мне не встречались заказы промышленного уровня под другие ОС. А лабораторки студентам соседнего ВУЗА можно склепать и платформозависимыми. Видимо только Linux готов для enterprise. Чаще всего попадаются заказы для древней версии gcc и ядра 2.4

средства манипулирования путями файлов

А что это? Или проблема к имени каталога прицепить имя файла?

получения информации о файлах

man stat

эквивалентное boost::lexical_cast<foo>(s)

Я понятия не имею, что это выражение делает

Torvus
()
Ответ на: комментарий от Reset

городить собственные велосипеды, а потом получается, что каждый пишет собственный велосипед вместо того, чтобы использовать стандратные средства и проект обрастает Си++ мхом

А с каких это пор boost стал стандартом?

В общем, по всему вышесказанному могу сделать вывод, что опыта промышленного программирования у тебя маловато

Скоропалительные выводы делаете, батенька

Torvus
()
Ответ на: комментарий от Torvus

А если серьезнее, то мне не встречались заказы промышленного уровня под другие ОС.

Это не значит, что у других их нет.

Или проблема к имени каталога прицепить имя файла? man stat

Ключевое слово - кроссплатформенно.

Begemoth ★★★★★
()
Ответ на: комментарий от Torvus

А с каких это пор boost стал стандартом?

С учётом того, сколько библиотек из boost'а попало в TR1, а затем в C++0x, можно говорить, что это почти стандарт.

Begemoth ★★★★★
()
Ответ на: комментарий от Torvus

Нет других ОС, кроме Linux.

всё, вопросов больше не имею, с вами мне всё понятно

Reset ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.