最有用或最惊人的STL短衬里

时间:2009-04-09 16:47:20

标签: c++ stl

我正在寻找几行C ++ / STL代码的实用和教育样本。我最喜欢的是:

  1. 清空一个释放其保留内存的向量:

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

    (与临时交换)

  2. 将地图复制到矢量:

    map<T1, T2> myMap;
    vector< pair<T1, T2> > myVec(myMap.begin(), myMap.end());
    // or
    myVec.assign(myMap.begin(), myMap.end());
    
  3. 自定义,非提升分割:

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

8 个答案:

答案 0 :(得分:13)

我最喜欢的是将容器复制到输出: 并将输入流复制到容器中。

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

答案 1 :(得分:7)

实际删除remove()remove_if()删除的元素需要以下习惯用语:

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

remove()remove_if()只是向前滑动未删除的元素并报告新范围结束的位置 - 它们不会(也不能)删除它们,因为它们可以在任意迭代器上工作范围,而不仅仅是一个容器。

答案 2 :(得分:6)

// 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提到的例子。

答案 3 :(得分:2)

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

答案 4 :(得分:2)

我最喜欢的是在委托代理中使用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的绑定和功能要好得多,但只有STL就可以完成。

答案 5 :(得分:1)

对于第二个示例,请使用值类型:

Copy a map to a vector:

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

答案 6 :(得分:0)

我喜欢这个用于循环文件中的每一行。来自Dobbs博士的Andrew Koenig专栏。

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

答案 7 :(得分:0)

将std :: for_each与lambda函数结合使用(自C ++ 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;
}

使循环更好看。