前言
在某些应用场景中,我们需要将某一容器内的元素放入另一个容器中,但是这两个容器的数据类型又是不同的。常见的解决方式就是循环遍历源容器,并在循环中改变元素的数据类型,同时放入目的容器中。
C++给我们提供了另一种方式,其主要原理和常见的解决方式是一样的,但是在代码上更加美观,那就是使用std::transform;
主要内容
std::transform函数原型
单范围版本
template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op );
InputIt
是输入迭代器类型,指向输入范围的开始和结束。OutputIt
是输出迭代器类型,指向存储结果的范围的开始。UnaryOperation
是一个一元操作,接受输入范围中的一个元素作为参数,并返回转换后的结果。这可以是一个函数、函数对象、Lambda表达式等。first1
和last1
分别指定输入范围的开始和结束迭代器。d_first
是输出范围的起始迭代器。- 函数返回输出范围的“下一个”迭代器,即最后一个被写入元素的下一个位置。
双范围版本
template< class InputIt1, class InputIt2, class OutputIt, class BinaryOperation >|
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOperation binary_op );
- 这个版本与单范围版本类似,但增加了第二个输入范围
InputIt2
和它的起始迭代器first2
。 BinaryOperation
是一个二元操作,接受两个输入范围中的对应元素作为参数,并返回结合后的结果。- 其余参数与单范围版本相同。
函数示例
示例一(单范围)
std::vector<int> src_vec = {1,2,3,4,5};
std::vector<std::string> dec_vec(src_vec.size());
std::transform(src_vec.begin(), src_vec.end(), dec_vec.begin(), [](int x){
return std::to_string(x);
});
在这里我们使用了lambda函数来作为UnaryOperation
示例二(单范围)
std::string ToString(int x)
{
return std::to_string(x);
}
int main(void)
{
std::vector<int> src_vec = {1,2,3,4,5};
std::vector<std::string> dec_vec(src_vec.size());
std::transform(src_vec.begin(), src_vec.end(), dec_vec.begin(), ToString);
}
在这里我们使用了一个函数作为UnaryOperation
示例三(双范围)
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2 = {10, 20, 30, 40, 50};
std::vector<int> result(vec1.size());
std::transform(vec1.begin(), vec1.end(), vec2.begin(), result.begin(),
std::plus<int>());
transform内没有指定vec2的范围,但是vec2依托于vec1的范围;
如果vec1的size 大于 vec2的size,并不会影响transform。
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2 = {10, 20, 30, 40};
std::vector<int> result(vec1.size());
std::transform(vec1.begin(), vec1.end(), vec2.begin(), result.begin(),
std::plus<int>()); // 将vec1和vec2中对应位置的元素相加
for (auto item : result)
{
std::cout << item << " , ";
}
// 程序结果
// 11 , 22 , 33 , 44 , 5 ,
注意事项
- 目的容器一定要在声明时 提前设置容器容量