tags:

views:

728

answers:

11

I cannot find this question on stockoverflow. But 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...

Let's share it...

One tip per answer...with code example --

Edit is it such a bad question as it resulting in downvotes?

+3  A: 

Using vector to replace pointer+new. That's huge.

Mark Ransom
+1  A: 

Most useful algorithm (IMHO) - std::for_each

Eric Petroelje
+5  A: 

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 );
anon
boost::lexical_cast :P
X-Istence
see original question - boost not allowed
anon
but that is pretty much exactly the source for lexical_cast anyway
1800 INFORMATION
@Neil: I am aware of that, I was just pointing out that is basically the same thing. I understand the original question specified no boost, and as such my post did not contain boost::lexical_cast even though it is extremely handy!
X-Istence
+5  A: 

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.

Paul
i have that book
Then I'm surprised you've asked this question :) Really :)
Paul
Telling people they are dumb for asking a question is not helpful.
catphive
+2  A: 

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>.

X-Istence
+3  A: 

Ask painter "what your favorite/most used brush?" :)

bb
If you're implying that it's useless I don't agree. They care about the raw materials they use too. Expressionists used big brushs to make rough strokes, realist painters use very fine ones and maybe pencils etc. Similar differences exist in programming.
I meant that STL had different tools for different goals. We cant compare, what tool I needed depended from my current task.
bb
+2  A: 

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.

Heather
+3  A: 

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.

T.E.D.
+1  A: 

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.

Anonymous
+3  A: 

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.
}
Martin York
+1  A: 

This is somewhat "evil", but it has saved us from many bugs:

#define FOREACH(iter,stlContainer)  \
for ( typeof(stlContainer.begin()) iter = stlContainer.begin(), \
                                   iter##End_Cached = stlContainer.end(); \
      iter != iter##End_Cached; \
      ++iter )

Using std::for_each is generally preferable, but has some disadvantages:

  • users must know a lot about the interactions between 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 boost
  • users may need to provide their own separate functor (usually a struct) for just a single point of use; said structs cannot be declared within the function surrounding the loop, leading to "non-locality" of related code -- it doesn't read as well as having the logic in-line with the flow of the rest of the function in some cases
  • it doesn't always nicely inline, depending on compiler

The FOREACH macro as listed above provides a few things:

  • like std::for_each, you won't get your boundary tests wrong (no iterating one past the end, etc)
  • it will use const_iterators over constant containers

Note 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.)

leander
Hah, the macro is missing some safety parens, will update that in a bit. Of course the usual "cons" of macro use all apply: repeated eval, etc, etc.
leander
Oh. Worth noting that this loop chooses to avoid repeatedly evaluating end(). It may or may not be wise depending on what you're doing in the loop. Of course, modifying the contents of a container as you're iterating is always a tricky proposition...
leander