#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
//通过transmpgrify函数将values中的全部元素追加到results的末尾
transform(values.begin(), values.end(), results.end(), transmogrify);
return 0;
}
上边这段代码虽然能编译通过,但是却不能运行,因为result.end()中没有对象,(result.end()+1)中更没有对象,*(result.begin())中也没有对象,这个代码将导致对无效对象的赋值操作。
可以调用back_inserter,该函数返回的迭代器使得push_back被调用,所以back_inserter适用于所有能提供push_back()方法的容器(vector/string/deque/list都行)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
//通过transmpgrify函数将values中的全部元素追加到results的末尾
transform(values.begin(), values.end(), back_inserter(results), transmogrify);
return 0;
}
同样课使用front_inserter,但是仅仅适用于提供该函数的容器,如deque/list
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
list<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
list<int> results;
//通过transmpgrify函数将values中的全部元素追加到results的末尾
transform(values.begin(), values.end(), front_inserter(results), transmogrify);
return 0;
}
如果想让transform将输出结果存放在results的前端,同时保留它们在values中原有的顺序,那么只需要俺相反的顺序来遍历values即可。
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
list<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
list<int> results;
//通过transmpgrify函数将values中的全部元素追加到results的末尾
transform(values.rbegin(), values.rend(), front_inserter(results), transmogrify);
return 0;
}
inserter将用于把结果插入到容器的任何位置。
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
//通过transmpgrify函数将values中的全部元素逐个加入results的中间
int len = results.size() / 2;
transform(values.begin(), values.end(), inserter(results, results.begin() + len), transmogrify);
return 0;
}
如果容器时vector或者是string,可以提前使用reserve,预留空间,从而提高插入操作的性能。
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
results.reserve(results.size() + values.size());//在results中为values预留空间
//通过transmpgrify函数将values中的全部元素逐个加入results的中间
int len = results.size() / 2;
transform(values.begin(), values.end(), inserter(results, results.begin() + len), transmogrify);
//同上,但这次results不需要重新分配内存空间
return 0;
}
但是当使用reserve提高一序列连续插入的效率的时候,切记reserve只是增加了容器的容量,而容器的大小并未改变。
因此下边的代码仍然是错的
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
results.reserve(results.size() + values.size());//在results中为values预留空间
//通过transmpgrify函数将values中的全部元素逐个加入results的中间
int len = results.size() / 2;
transform(values.begin(), values.end(), results.end(), transmogrify);
//同上,但这次results不需要重新分配内存空间
return 0;
}
改成下边的这样就能解决上述问题:
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
results.reserve(results.size() + values.size());//在results中为values预留空间
//通过transmpgrify函数将values中的全部元素逐个加入results的中间
int len = results.size() / 2;
transform(values.begin(), values.end(), back_inserter(results), transmogrify);
//同上,但这次results不需要重新分配内存空间
return 0;
}
如果只是想简单的覆盖容器中原本的元素,那么久需要确保results中至少有的元素和values一样多,可以使用下边的代码:
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
if (results.size() < values.size())
{
results.resize(values.size());
}
transform(values.begin(), values.end(), results.begin(), transmogrify);
//同上,但这次results不需要重新分配内存空间
return 0;
}
或者,可以先清空results,然后再resultd的末尾插入:
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<list>
using namespace std;
int transmogrify(int x)//根据x的值生成新的值
{
return x + 2;
}
int main()
{
vector<int> values;
for (int i = 1; i <= 5; i++)
{
values.push_back(i);//将结果加在values的末尾
}
vector<int> results;
results.clear();//清空results
results.reserve(values.size());
transform(values.begin(), values.end(), back_inserter(results), transmogrify);
//同上,但这次results不需要重新分配内存空间
return 0;
}
本条款论证了这个主题的很多变化,但我希望你能牢牢记住本质。无论何时你使用一个要求指定目的区间的算法,确保目的区间已经足够大或者在算法执行时可以增加大小。如果你选择增加大小,就使用插入迭代器,比如ostream_iterators或从back_inserter、front_inserter或inserter返回的迭代器。这是所有你需要记住的东西。