Подтвердить что ты не робот

Самые полезные или удивительные короткие лайнеры STL

Я ищу практические и образовательные образцы кода С++/STL в нескольких строках. Мои фактические фавориты:

  • Пусто вектор, освобождающий его зарезервированную память:

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

    (своп с временным)

  • Скопируйте карту в вектор:

    map<T1, T2> myMap;
    vector< pair<T1, T2> > myVec(myMap.begin(), myMap.end());
    // or
    myVec.assign(myMap.begin(), myMap.end());
    
  • Пользовательский, невосстанавливаемый раскол:

    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;
    }
    
4b9b3361

Ответ 1

// 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 ) );  

не очень полезный, но мощный:

проверка сортируется в контейнере

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

также примеры, упомянутые вами и dirkgently.

Ответ 2

Мое избранное - копирование контейнеров на выход: И копирование входного потока в контейнер.

#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")
             );
}

Ответ 3

Для удаления элементов, удаленных с помощью remove() или remove_if(), требуется следующая идиома:

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

remove() и remove_if() просто перемещают не удаленные элементы вперед и сообщают, где заканчивается новый диапазон - они не (и не могут) их удалять, потому что они могут работать на любом произвольном диапазоне итераторов, а не только контейнер.

Ответ 4

copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(),
     ostream_iterator<char>(cout));

Другая используемая идиома - инициализация контейнера из массива:

#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;
}

Но если вы хотите чистую магию, посмотрите Boost Lambda Library;) Пример:

vector<int*> vp(10); 
sort(vp.begin(), vp.end(), *_1 > *_2);

Ответ 5

Мне больше всего нравится использовать bind1st/bind2nd/mem_fun в виде делегатов.

// 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));

Использование boost bind и функции намного лучше, но впечатляет, что можно сделать только с помощью STL.

Ответ 6

Для вашего второго примера используйте тип значения:

#

Copy a map to a vector:

typedef map<T1, T2> MyMap;
MyMap myMap;
vector< MyMap::value_type > myVec(myMap.begin(), myMap.end());

Ответ 7

Мне нравится этот цикл для каждой строки в файле. Из колонки Эндрю Кенига в докторе Доббсе.

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

Ответ 8

Использование std:: for_each в сочетании с лямбда-функцией (начиная с С++ 11)

std::vector<int> v(20);

std::for_each( v.begin(), v.end(), [] (int item)
{
    std::cout << item;
} );

вместо

for(std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)
{
    std::cout << *it;
}

делает для более перспективных циклов.