Russian Qt Forum
Ноябрь 23, 2024, 11:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование find_if [РЕШЕНО]  (Прочитано 11919 раз)
sergeyvl12
Гость
« : Октябрь 19, 2009, 12:20 »

Добрый день,

class SomeClass
{
    ...
public:
    int getSomeValue() const;
    ...
};

...

std::vector<SomeClass> values;

так вот, хочу с помощью std::find_if найти первое значение больше 0.

Свой функционал писать не хочу. Можно ли выкрутиться стандартными?

« Последнее редактирование: Октябрь 28, 2009, 10:49 от sergeyvl12 » Записан
crackedmind
Гость
« Ответ #1 : Октябрь 19, 2009, 15:54 »

Напиши свой предикат, который будешь передавать в find_if
Записан
sergeyvl12
Гость
« Ответ #2 : Октябрь 19, 2009, 16:00 »

Напиши свой предикат, который будешь передавать в find_if

Может быть я не точно выразился, но я сказал что свой функционал (или предикат, если так больше нравится) писать не хочу.

С предикатом было бы просто:

std::find_if(values.begin(),values.end(),MyPredicate())

однако вопрос в том, можно ли составить этот предикат, используя стандартные и не реализуя класс MyPredicate ?
Записан
crackedmind
Гость
« Ответ #3 : Октябрь 19, 2009, 16:14 »

Для своих типов данных придется писать.
Записан
Tonal
Гость
« Ответ #4 : Октябрь 20, 2009, 07:31 »

Код:
std::find_if(values.begin(), values.end(), bind(&SomeClass::getSomeValue, _1) > 0);
Оно?
bind ищи в Boost-е или в stl нового стандарта. Улыбающийся
В  gcc 4.4.0 это пространство имён stl::tr1
Записан
sergeyvl12
Гость
« Ответ #5 : Октябрь 20, 2009, 14:42 »

Код:
std::find_if(values.begin(), values.end(), bind(&SomeClass::getSomeValue, _1) > 0);
Оно?
bind ищи в Boost-е или в stl нового стандарта. Улыбающийся
В  gcc 4.4.0 это пространство имён stl::tr1

Спасибо, это видимо оно. Только нет у меня сейчас нового стандарта Грустный (Visual Age С++ 6.0 под AIX)
Записан
Tonal
Гость
« Ответ #6 : Октябрь 21, 2009, 08:29 »

Ну и посмотри в его доке чего именно он поддерживает.
Посмотри в доке на свою версию Boost-а про AIX.
Записан
sergeyvl12
Гость
« Ответ #7 : Октябрь 22, 2009, 11:20 »

Ну и посмотри в его доке чего именно он поддерживает.
Посмотри в доке на свою версию Boost-а про AIX.

boost скомпилить под аиксом не удается целяком (старый компилятор). Реализация stl под AIX такие вещи делать не умеет.

Нашли относительно безболезненный выход: перетянули compose1 (есть не во всех версиях stl).

Теперь это выглядит так;

Код:
std::vector<SomeClass>::iterator iter =
        std::find_if(values.begin(),
                     values.end(),
                     aux::compose1(std::bind2nd(std::greater<int>(),0),
                                   std::mem_fun_ref(&SomeClass::getSomeValue)));

Записан
crackedmind
Гость
« Ответ #8 : Октябрь 23, 2009, 05:03 »

А не проще было предикат свой написать? Улыбающийся
Записан
Tonal
Гость
« Ответ #9 : Октябрь 23, 2009, 08:49 »

Boost "целиком" компилить не нужно. Там большинство библиотек - только в хедерах. И bind, и lambda именно такие.
Так что вам нужно было просто проверить компиляемость. Улыбающийся
Записан
sergeyvl12
Гость
« Ответ #10 : Октябрь 23, 2009, 10:45 »

А не проще было предикат свой написать? Улыбающийся

Да оно то может быть и проще если предикат достаточно сложный. Но дело в том что это в таких простых случаях усложняет читабельность и сопровождаемость кода ( для дого чтобы понять что происходит в коде, приходится смотреть предикат, который может быть описан не здесь, а где-то ). А так все перед глазами. Конечно форма с compose1 - это тоже не выход (слишком громоздко и не читабельно). Поэтому буду пробивать boost.
Записан
sergeyvl12
Гость
« Ответ #11 : Октябрь 23, 2009, 11:02 »

Boost "целиком" компилить не нужно. Там большинство библиотек - только в хедерах. И bind, и lambda именно такие.
Так что вам нужно было просто проверить компиляемость. Улыбающийся


Это да, но с другой стороны:

1. Даже если это и хидера - их так просто не вытащишь (потому что они как правило зависят от других частей буста);
2. Желательно также было бы к boost::bind иметь какие-то тесты чтобы проверить что оно хотя-бы работает под аиксом.

В связи с этим вопрос - как корректно установить буст частично (на данный момент мне нужен boost::bind + тксты к нему). Возможно ли это? В инсталляторе буста я пока не разобрался.
Записан
crackedmind
Гость
« Ответ #12 : Октябрь 23, 2009, 12:51 »

В составе буста идет прога которая вытаскивает нужную либу с минимальными зависимостями.

Цитировать
The bcp utility is a tool for extracting subsets of Boost, it's useful for Boost authors who want to distribute their library separately from Boost, and for Boost users who want to distribute a subset of Boost with their application.

bcp can also report on which parts of Boost your code is dependent on, and what licences are used by those dependencies.
Записан
Tonal
Гость
« Ответ #13 : Октябрь 27, 2009, 09:43 »

В связи с этим вопрос - как корректно установить буст частично (на данный момент мне нужен boost::bind + тксты к нему). Возможно ли это? В инсталляторе буста я пока не разобрался.
Эжели используются только header-only либы - то всё просто.
 1. Утянул последний архивчик с сайта,
 2. Развернул его куда-нибудь.
 3. Добавил путь к этому куда-нибудь в пути инклюдов проекта. Улыбающийся
Записан
sergeyvl12
Гость
« Ответ #14 : Октябрь 28, 2009, 10:48 »

Спасибо всем кто ответил.

Резюмирую:

1. Вычленять что-то из буста наверное нет смысла. Попробовал с помощью bcp вычленить bind. Оказалось что вычленилось где-то 500 файлов (из 7000);
2. Лучше поставить весь буст и юзать пока только хидера (вернее те из них что сможет подхватить наш древний компилятор )
3. Поставил буст, написал тест для bind:

Код:
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

#include <boost/bind/bind.hpp>

class Person
{
    std::string name_;

public:
    Person( const std::string& name )
        : name_( name )
    {}

    std::string getName() const
    { return name_; }
};

int main()
{
    std::vector<Person> people;

    people.push_back(Person("Jack"));
    people.push_back(Person("John"));
    people.push_back(Person("Martin"));
    people.push_back(Person("Peter"));

    std::vector<Person>::iterator
        iter(std::find_if(people.begin(), people.end(), boost::bind( &Person::getName, _1 ) == "Peter" ));

    std::cout << iter->getName() << std::endl;
}

тест заработал.

Значит как минимум bind можно использовать.

Постепенно начнем использовать и другие библиотеки. Всем спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 21.