Reputation:
I am wondering how people use STL (No fancy boost)... just an ol' fashion STL. Tricks/tips/mostly used cases acquired over many, many years... and perhaps gotchas...
Upvotes: 6
Views: 3364
Reputation: 264401
I love the istream_iterator and the ostream_iterator.
A nice easy way of reading a stream and making it look like any other container:
// Copies a stream of integers on the std input
// into a vector.
int main()
{
std::vector<int> data;
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<>(),
std::back_inserter(data)
);
// By uisng the istream_iterator<> the input just becomes another container.
}
// Or even simpler:
int main()
{
std::vector<int> data(std::istream_iterator<int>(std::cin),
std::istream_iterator<>()
);
// By uisng the istream_iterator<> the input just becomes another container.
}
Upvotes: 6
Reputation: 8727
The following is somewhat "evil", but it has saved us from many bugs.
(Update, thanks to @Ricky65's comment for drawing me back here.) C++11 has a range-based for loop that is far superior to this, if your compiler supports it; we still work with some really old compilers, though.
#define FOREACH(iter,stlContainer) \ for ( typeof(stlContainer.begin()) iter = stlContainer.begin(), \ iter##End_Cached = stlContainer.end(); \ iter != iter##End_Cached; \ ++iter )
(Further update, credit to the Boost devs.) It is loosely based on the more complicated but more capable BOOST_FOREACH
macro, but has the advantage of being much easier to step through in debug builds for small cases, and not requiring a small pile of boost headers (which in some codebases/groups is verboten).
Using std::for_each
is generally preferable, but has some disadvantages:
bind1st
/ bind2nd
/ ptr_fun
/ mem_fun
to use it effectively for non-trivial "visitation" -- boost fixes a lot of these issues, but not everyone has or knows boostThe FOREACH macro as listed above provides a few things:
std::for_each
, you won't get your boundary tests wrong (no iterating one past the end, etc)const_iterators
over constant containersNote that it does require a somewhat nonstandard "typeof" extension.
A typical usage might be:
list< shared_ptr< Thing > > m_memberList; // later FOREACH( iter, m_memberList ) { if ( (*iter)->getValue() < 42 ) { doSomethingWith( *iter ); } }
I'm not entirely happy with this macro, but it has been invaluable here, especially for programmers without as much experience in STL-aware design.
(Please feel free to point out pros/cons/flaws, I'll update the answer.)
Upvotes: 1
Reputation: 18631
The functional
stuff: bind1st
, bind2nd
, mem_fun
, equal_to
, etc. is pretty useful if for some reason one doesn't have access to Boost Bind.
It's very subjective question and much depends on your team coding style, project type, and other unknown factors.
Upvotes: 2
Reputation: 44804
I love vector. It's what C++ arrays should have been. I do a lot of real-time work though. Folks who don't need determinisim might prefer list.
Just about everyone uses the heck out of string.
I don't get to use algorithm much, as we still use VS6 here (which can't handle complex template instatiations). That will pass soon though.
Upvotes: 4
Reputation:
I can't recall having a favorite or most used algorithm/predicate/iterator, just the one that did the best job for what I was trying to accomplish at the time.
Upvotes: 2
Reputation: 16667
I use the STL in almost all of my projects, for things from loops (with iterators) to splitting up the input into a program.
Tokenise an input string by spaces and input the result into an std::vector for parsing later:
std::stringstream iss(input);
std::vector<std::string> * _input = new std::vector<std::string>();
std::copy(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>(),
std::back_inserter<std::vector<std::string> >(*_input));
Other favourites off course are std::reverse and various other algorithms defined in <algorithm>
.
Upvotes: 7
Reputation: 13238
There are no most used STL algorithms, predicates or iterators. It's like asking what is the most used operator in C++ language. What do you use more often, operator+
or operator-
? Do you prefer if
to while
? Or maybe to throw
?
Everything is used when it has to be used.
PS: I suggest you to read Effective STL by Scott Meyers before asking such questions.
Upvotes: 1
Reputation:
My favourite is the following to change anything streamable to a string:
template <class TYPE> std::string Str( const TYPE & t ) {
std::ostringstream os;
os << t;
return os.str();
}
Then:
string beast = Str( 666 );
Upvotes: 9