STL Function???

Does anyone know if there is a STL function that will return a set of data? I would like to do what find () does, but find only returns the first one. for example, if i had a vector of Person objects, I want something that could return me all Person's with last name of smith.

I know i could do a linear search myself, but wanted to see if the STL had something similar.
You could loop it and use the position(in this case vector element) + 1 as the new start value. This is an example of some code I wrote a while back that searched a html file for tags and used a looped find():

1
2
3
4
5
6
7
8
9
10
	while(true) {
		leftBracket = fileContent.find_first_of('<',rightBracket);
		if(leftBracket==std::string::npos)
			break;
		rightBracket = fileContent.find_first_of('>',leftBracket)+1;
				
		stackElement = createSubString(ptr_fileContent, leftBracket, rightBracket); // get tag to put in stack

		myStack.push(stackElement);
	}
firedraco, thanks for the link. i'm trying to implement that, but i came across a compile error i can't figure out. can anyone please help me?

Foo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef FOO_H_
#define FOO_H_

class Foo
{
 public:
  Foo (int value) : value_(value) {}
  ~Foo () {};

 private:
  int value_;
};

class FooPtr
{
 public:
  FooPtr (Foo *fooPtr) : fooPtr_(fooPtr) {}

 private:
  Foo *fooPtr_;
};
#endif /* FOO_H_ */ 


bar.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef BAR_H_
#define BAR_H_

#include "foo.h"

class Bar
{
 public:
  Bar ();
  ~Bar ();
  void myTest ();

 private:
  bool isOdd (FooPtr ptr);
};

#endif /* BAR_H_ */ 


bar.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <vector>
#include <iostream>
#include "bar.h"

using namespace std;

Bar::Bar ()
{

}

Bar::~Bar ()
{

}

void Bar::myTest ()
{
  vector<FooPtr> myVector;

  for (int i=0; i<10; i++)
    {
      Foo f (i);
      myVector.push_back (FooPtr (&f));
    }

  cout << "size of myVector:" << myVector.size () << endl;
  
  // ---- help!! line below causes a compile error
  //remove_if (myVector.begin (), myVector.end (), &Bar::isOdd);
}


bool Bar::isOdd (FooPtr ptr)
{
  cout << "isOdd ()" << endl;
  return true;
}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
#include "foo.h"
#include "bar.h"

using namespace std;

int main ()
{
  Bar b;
  b.myTest ();
}


compile
 
g++ main.cpp bar.cpp -o main


the error message, which i don't know how to fix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ g++ main.cpp bar.cpp -o main
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h: In function `_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, _OutputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _OutputIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]':
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:1147:   instantiated from `_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]'
bar.cpp:29:   instantiated from here
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:1074: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h: In function `_RandomAccessIterator std::find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]':
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:336:   instantiated from `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:1145:   instantiated from `_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]'
bar.cpp:29:   instantiated from here
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:259: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:263: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:267: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:271: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:336:   instantiated from `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:1145:   instantiated from `_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<FooPtr*, std::vector<FooPtr, std::allocator<FooPtr> > >, _Predicate = bool (Bar::*)(FooPtr)]'
bar.cpp:29:   instantiated from here
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:279: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:283: error: must use .* or ->* to call pointer-to-member function in `__pred (...)'
c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:287: error: must use .* or ->* to call pointer-to-member function in `__pred (...)' 

A function or function object is needed rather than a member function to be used as predicator(&Bar::isOdd). The members of a class do not have addresses until they are referred to an object. In your case, &Bar::isOdd is only an offset rather than an function address.

I modify files bar.h & bar.cp, then the compile is working

bar.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef BAR_H_
#define BAR_H_

#include "foo.h"

class Bar
{
 public:
  Bar ();
  ~Bar ();
  void myTest ();

 private:
//  bool isOdd (FooPtr ptr);
};

#endif /* BAR_H_ */ 



bar.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <algorithm>
#include <vector>
#include <iostream>
#include "bar.h"

using namespace std;
bool isOdd (FooPtr ptr)
{
  cout << "isOdd ()" << endl;
  return true;
}


Bar::Bar ()
{

}

Bar::~Bar ()
{

}

void Bar::myTest ()
{
  vector<FooPtr> myVector;

  for (int i=0; i<10; i++)
    {
      //Foo f (i);
      myVector.push_back (FooPtr (new Foo(i)));
    }

  cout << "size of myVector:" << myVector.size () << endl;
  
  // ---- help!! line below causes a compile error
  remove_if (myVector.begin (), myVector.end (), isOdd);
}

/*
bool Bar::isOdd (FooPtr ptr)
{
  cout << "isOdd ()" << endl;
  return true;
}*/

Thank you Dennis for your explanation and correction to my example. Things work now. I acutally made isOdd a friend of the class. Thanks again!
It depends on what you want to do. remove_if will cause you to lose some data. If you are trying to keep person objects with some name and get rid of all others, remove_if is fine. If you simply want to identify those with some name while keeping all others it is harder.
remove_if is the most horribly named function ever. It will just change the order of the elements; it doesn't actually
remove them from the container.
Topic archived. No new replies allowed.