tags:

views:

936

answers:

7

I'm looking for practical and educational samples of C++ / STL code fitting in few lines. My actual favorites are:

  1. Empty a vector freeing its reserved memory:

    vector <...>().swap (v)
    

    (swap with a temporary)

  2. Copy a map to a vector:

    map<T1, T2> myMap;
    vector< pair<T1, T2> > myVec(myMap.begin(), myMap.end());
    // or
    myVec.assign(myMap.begin(), myMap.end());
    
  3. Custom, non-boost split:

    vector<string> &mysplit(const string &s, char delim, vector<string> &elems) {
        stringstream ss(s);
        string item;
        while(getline(ss, item, delim)) { elems.push_back(item); }
        return elems;
    }
    
+2  A: 
copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(),
     ostream_iterator<char>(cout));

Another oft used idiom is initializing a container from an array:

#include <map>
using namespace std;

int main() {
    typedef std::map<char,int> LUT;
    typedef LUT::value_type LUT_item_t;

    const LUT_item_t items[] = { LUT_item_t('b',1), 
                                 LUT_item_t('a',5) 
                               };

    LUT my_map(items, items + sizeof items/sizeof items[0]);
    return 0;
}

But if you want pure magic, look into Boost Lambda Library ;) A sample:

vector<int*> vp(10); 
sort(vp.begin(), vp.end(), *_1 > *_2);
dirkgently
Common mistake here. Because the istream_iterator uses the >> operator white space will be deleted. To compensate for this you should use the istreambuf_iterator to make sure you preserve white space.
Martin York
@Martin York: Right. I'll fix it.
dirkgently
+4  A: 
// std::back_inserter usage ( std::inserter for map )
std::copy( source.begin(), source.end(), std::back_inserter( container ) );

-

// mem_fun and bind usage (but boost better)
std::some_algorithm(..., std::mem_fun( func ) );

not so useful, but powerful:

check is container sorted

std::adjacent_find( container.begin(), container.end(), greater<Container::value_type>() ) == container.end()

also examples mentioned by you and dirkgently.

bb
The adjacent_find example is nifty.
+1 for adjacent_find() :)
j_random_hacker
+1  A: 

For your second example use the value type:

#

Copy a map to a vector:

typedef map<T1, T2> MyMap;
MyMap myMap;
vector< MyMap::value_type > myVec(myMap.begin(), myMap.end());
Martin York
+10  A: 

My favorite is copying containers to the output: And copying the input stream into a container.

#include <vector>
#include <algorithm> 
#include <iterator>
#include <iostream>

int main()
{
    std::vector<int>   data;
    std::copy(std::istream_iterator<int>(std::cin),
              std::istream_iterator<int>(),
              std::back_inserter(data)
             );

    std::copy(data.begin(),data.end(),
              std::ostream_iterator<int>(std::cout,"\n")
             );
}
Martin York
+6  A: 

The following idiom is needed to actually remove the elements removed by remove() or remove_if():

vector<int> v;
...
v.erase(remove(v.begin(), v.end(), 42), v.end());

remove() and remove_if() just slide non-removed elements forward and report where the new range ends -- they don't (and can't) delete them because they can work on any arbitrary iterator range, not just a container.

j_random_hacker
+2  A: 

What I like most is to use bind1st/bind2nd/mem_fun in sort of delegates.

// will call a->func(v[i])
for_each(v.begin(), v.end(), bind1st(mem_fun(&A::func), &a));

// will call w[i]->func(72)
for_each(w.begin(), w.end(), bind2nd(mem_fun(&A::func), 72));

Using boost's bind and function are much better, but it is impressive which can be done with just STL.

Ismael
I would probably select your post as an accepted answer now. It would be a little bit political though, because what I would like to show by this acceptation, is that boost::bind is overused in simple situations where STL is just sufficient.
A: 

I like this one for looping over each line in a file. From a Andrew Koenig column in Dr. Dobbs.

for (string s; getline(stream,s); ) {
  // Process line
}
Jack Nock