Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Почему не срабатывает поиск по вектору.


Автор: tararataka 2.9.2010, 14:25
Мне нужно найти пару, первое поле которой совпадает с первым полем шаблона. Почему не срабатывает приведённый код? В найденном итераторе всегда оказывается первый элемент.  smile 
Код

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

bool linksearch(pair<string, int>* a, pair<string, int> b) {
    return ((a->first) == (b.first));
}
int main() {
        vector< pair<string, int >* > ghostS;   // вектор в котором буду искать
        vector< pair<string, int >* >::iterator iter;
        ghostS.push_back(new pair<string, int>("River", 1) );       // заполнение элементами
        ghostS.push_back(new pair<string, int>("long", 1) );
        ghostS.push_back(new pair<string, int>("Belive", 1) );

        pair<string, int> * tempalt = new pair<string, int>("Belive", 1); // шаблон поиска
        iter = search(ghostS.begin(),ghostS.end(), tempalt, tempalt, linksearch); // поиск
        cout << (*iter)->first <<endl; // и нифига
        system("PAUSE");
    return 0;
}

Автор: azesmcar 2.9.2010, 14:28
 smile 
знакомься - http://www.cplusplus.com/reference/stl/map/

Автор: tararataka 2.9.2010, 14:36
Да знаю я про map,  smile но он мне не подходит.

Автор: azesmcar 2.9.2010, 14:36
Цитата(tararataka @  2.9.2010,  14:36 Найти цитируемый пост)
Да знаю я про map,  smile но он мне не подходит. 

и чем же?

Автор: ИванМ 2.9.2010, 14:42
tararataka, чтобы заработало достаточно изменить строку:
Код

iter = search(ghostS.begin(),ghostS.end(), tempalt, tempalt+1, linksearch);

Другое дело, конечно, что код ужасен.

Автор: tararataka 2.9.2010, 15:18
azesmcar
Цитата
и чем же?

Короче мне нужно иметь один контейнер отсортированным различным образом, плюс нужно постоянно добавлять элементы в него. Ну и что-бы не извращаться, я решил все операции выполнять на различных контейнерах, состоящих из ссылок на одни  и те-же элементы.

А map сортируется только по первому значению, если я хочу по второму, то мне нужно свопнуть пару. Но сделать это нужно так, что-бы она оставалась одной и той же парой. Я х.з. как это сделать.  smile

ИванМ
Цитата
чтобы заработало достаточно изменить строку:

Ох блин, я совсем про это не подумал.  Да, теперь всё корректно. smile 

Цитата

Другое дело, конечно, что код ужасен. 

Эээ.  smile Почему это ужасен? 

Автор: ИванМ 2.9.2010, 15:33
Цитата(tararataka @  2.9.2010,  15:18 Найти цитируемый пост)
Эээ.  smile Почему это ужасен?  

1. использование vector не по назначению
Цитата(tararataka @  2.9.2010,  15:18 Найти цитируемый пост)
нужно постоянно добавлять элементы в него

В vector'е при таких манипуляциях будет происходить перезапись элементов. Лучше использовать list - как раз для таких целей.
2. использование алгоритмов не по назначению - для вашей цели подошел бы find_if.
3. лучше вообще отказаться от указателей (при динамическом выделении памяти), используйте "умные" указатели (а в вашем случае можно вообще использовать статические данные), а если уж вы это делаете, то привыкайте освобождать выделенную память - вы этого не делаете
4. не очень важно, но все же: многоуровневые шаблоны - не читабельно и плохой стиль программирования
Используйте классы или typedef

Автор: tararataka 2.9.2010, 16:22
Цитата

2. использование алгоритмов не по назначению - для вашей цели подошел бы find.

В find нельзя передать собственный предикат, а мне он нужен, так как у меня равные элементы не те, которые полностью равны, а у которых совпадает только часть first.

Цитата

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

Забыл написать, мне нужно изменять значения некоторых элементов.

Цитата

привыкайте освобождать выделенную память - вы этого не делаете

Типа если я свои вектора указателей снесу, то на что они ранее указывали останется? 

Цитата
используйте "умные" указател

Первый раз слышу, надо погуглить.

Автор: ИванМ 2.9.2010, 16:30
Цитата(tararataka @  2.9.2010,  16:22 Найти цитируемый пост)
В find нельзя передать собственный предикат

Вы быстро ответили.. Я изменил find на find_if

Цитата(tararataka @  2.9.2010,  16:22 Найти цитируемый пост)
Забыл написать, мне нужно изменять значения некоторых элементов.

Это можно делать и со статическими элементами (статические - я имел ввиду, которые без new).

Цитата(tararataka @  2.9.2010,  16:22 Найти цитируемый пост)
Типа если я свои вектора указателей снесу, то на что они ранее указывали останется?

Да

Цитата(tararataka @  2.9.2010,  16:22 Найти цитируемый пост)
используйте "умные" указател
Первый раз слышу, надо погуглить.

Правильно. И советую сразу которые в boost - shared_ptr и ему подобные. auto_ptr не рекомендую, т.к. его нельзя использовать в контейнерах.

Автор: tararataka 3.9.2010, 08:02
ИванМ
Цитата

Я изменил find на find_if

В find_if нельзя передавать шаблон поиска. smile
Код

template <class InputIterator, class Predicate>
   InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred );


Цитата

Это можно делать и со статическими элементами (статические - я имел ввиду, которые без new).

Так их же вроде нельзя создать неопределённое количество?

Автор: mrbrooks 3.9.2010, 08:13
Цитата(tararataka @  3.9.2010,  09:02 Найти цитируемый пост)
В find_if нельзя передавать шаблон поиска. 

не совсем понятно о чем это ты? почему не устраивает предикат?
Цитата(ИванМ @  2.9.2010,  17:30 Найти цитируемый пост)
Правильно. И советую сразу которые в boost - shared_ptr и ему подобные. auto_ptr не рекомендую, т.к. его нельзя использовать в контейнерах.

если компилятор поддерживает tr1 - то в нем это уже есть.

Автор: tararataka 3.9.2010, 13:48
mrbrooks
Цитата

не совсем понятно о чем это ты? почему не устраивает предикат?

Потому что шаблоны поиска у меня разные, ну всмысле, я наперёд не знаю что буду искать. А передавать что-либо в функцию не через её аргументы - не кошерно.

Автор: tararataka 3.9.2010, 14:05
fix Ой, в предикат тоже можно передать значение. 

Автор: Леопольд 3.9.2010, 14:44
Цитата(tararataka @  2.9.2010,  15:18 Найти цитируемый пост)
Короче мне нужно иметь один контейнер отсортированным различным образом, плюс нужно постоянно добавлять элементы в него. Ну и что-бы не извращаться, я решил все операции выполнять на различных контейнерах, состоящих из ссылок на одни  и те-же элементы.
Т.е. хранить в других контейнерах итераторы того, где лежат инстансы? Для вектора это неудачная идея, он может переаллоцировать память и старые итераторы станут невалидными.

Автор: ИванМ 6.9.2010, 11:13
Цитата(tararataka @  3.9.2010,  08:02 Найти цитируемый пост)
Так их же вроде нельзя создать неопределённое количество? 

Нельзя точно также как и динамические. Грубо говоря, элементы, переданные в контейнер, будут по-любому динамическими. Будут храниться в выделенной памяти.

Цитата(mrbrooks @  3.9.2010,  08:13 Найти цитируемый пост)
если компилятор поддерживает tr1 - то в нем это уже есть. 

Я в основном на VS2008. Читал, что tr1 там есть, но я его не смог найти.

Автор: tararataka 7.9.2010, 06:50
А я могу с помощью дебаггера найти участки памяти, на которые ничто не указывает?

Автор: Леопольд 7.9.2010, 09:42
tararataka, если речь про утечки памяти, то, вроде, valgrind может помочь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)