您的位置:首页 > 编程语言 > C语言/C++

STL通用算法: for_each,c++11标准范围for,transform.

2017-11-17 20:14 441 查看
之前的算法都用到了for_each算法把容器内的元素输出到屏幕上,所以今天讲讲for_each这个算法,还有和它功能类似的范围for的用法.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
void operator()(T a)
{
cout << a << " ";
}
};

int main()
{
vector<int> s = {1,2,5,7,4,6,9};

for_each(s.begin(), s.end(), Print<int>());//输出1 2 5 7 4 6 9
cout << endl;

system("pause");
return 0;
}


看完上面非常简单的代码后,可能就会有小伙伴会问了,既然可以用for_each来代替我们手写的for循环来输出容器内的元素,那么是否可以用for_each这个算法来给容器内的值进行一些操作呢,那当然是可以的啊,下面看实现的代码:

template <typename T>
class Print
{
public:
//只要在这里加个引用就可以实现了,因为a作为形参作为左操作数,而容器内的元素则作为右操作数,a相当于是容器内元素的别名,所以当然可以进行值的操作呗.
void operator()(T &a)
{
a++;
cout << a << " ";
}
};


for_each手动实现:在STL源码剖析中,SGI版本里for_each是有返回值的,但是此返回值无用,所以这里就不放返回值了.

template <typename T, typename C>
void myFor_each(T &first, T &last, C function)
{
while (first != last)
{
function(*first);
first++;
}
}


在C++11标准中,多了一个范围for的用法,接下来我们来看看:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
void operator()(T a)
{
cout << a << " ";
}
};

int main()
{
vector<int> s = {1,2,5,7,4,6,9};

//和我们以前使用的for循环不太一样,用temp临时变量作为容器s内一个元素的别名,然后进行操作,当然可以改变值啦!
for (auto &temp : s)
{
temp += 1;
cout << temp << " ";
}
cout << endl;

system("pause");
return 0;
}


从在原容器元素的基础上修改元素的功能来看,transform同样能实现相同的功能.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
void operator()(T a)
{
cout << a << " ";
}
};

template <typename T>
class myPlus
{
public:
int operator()(T a)
{
return a + 5;
}
};

int main()
{
vector<int> s = { 1, 2, 5, 7, 4, 6, 9 };

//transform算法用来产生一个新序列,然后把新序列赋值给一个容器.此例是直接覆盖原容器的元素.
//给每一个元素+5,然后从s.begin()这个迭代器开始赋值.当然别的容器也可以~不过容器内的元素数量必须要超过容器s,否则会报错.
transform(s.begin(), s.end(), s.begin(), myPlus<int>());
for_each(s.begin(),s.end(),Print<int>());
cout << endl;

system("pause");
return 0;
}


这里是transform的实现.注意返回值是新序列中最后一个元素的后一个元素,等同于s.end().

template <typename T, typename C>
T myTransform(T first, T last, T new_first, C function)
{
while (first != last)
{
*new_first++ = function(*first++);
}
return new_first;
}


transform还有一个重载用法,是用两个序列产生一个新序列.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class Print
{
public:
void operator()(T a)
{
cout << a << " ";
}
};

template <typename T>
class myPlus
{
public:
int operator()(T a, T b)
{
return a + b;
}
};

int main()
{
vector<int> s = { 1, 2, 5, 7, 4, 6, 9 };
vector<int> temp(s.size(),10);

//把两个序列的所有值全部相加,产生的新序列赋值给了容器s.
//注意,第二个序列的元素必须要大于等于第一个序列的元素,否则会报错.
transform(s.begin(), s.end(), temp.begin(),s.begin(), myPlus<int>());
for_each(s.begin(), s.end(), Print<int>());
cout << endl;

system("pause");
return 0;
}


template <typename T, typename C>
T myTransform(T first, T last, T first_2, T new_first, C function)
{
while (first != last)
{
*new_first++ = function(*first++,*first_2++);
}
return new_first;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl