我有一个没有push_back()
方法的容器。但是此容器在begin()
和end()
上有一个迭代器。
我想使用std::transform()
输出到该容器中。但是std::back_inserter
需要在输出容器上调用push_back()
。
是否可以使用std::transform()
输出到仅支持直接分配的容器中?喜欢:
for (auto item : containerNoPushBack)
{
item = calculateValue();
}
或像这样的索引分配:
for (size_t i = 0; i < containerNoPushBack.size(); ++i)
{
item[i] = calculateValue();
}
答案 0 :(得分:3)
如果您可以执行item[i]
(即您的容器中有足够的元素),则只需在your_container.begin()
中使用std::transform
,而无需使用std::back_inserter
。 std::back_inserter
只是避免在应用容器之前显式调整容器大小的好方法。
以下片段均将my_output
的内容填充到my_input
中:
std::vector<int> my_output;
std::transform(my_input.begin(), my_input.end(), std::back_inserter(my_output), [](const auto& arg){return arg;});
std::vector<int> my_output;
my_output.resize(my_input.size());
std::transform(my_input.begin(), my_input.end(), my_output.begin(), [](const auto& arg){return arg;});
答案 1 :(得分:2)
std::transform
确实使用“直接分配”。仅当您需要推送元素时才使用back_inserter
,如果目标中已有元素,则不需要。
考虑可能的实现方式(取自cppreference):
template<class InputIt, class OutputIt, class UnaryOperation> OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op) { while (first1 != last1) { *d_first++ = unary_op(*first1++); } return d_first; }
std::transform
本身不执行任何操作。正是由于这个原因,您需要一个back_inserter
。但是,您可以调整目标的大小以为转换后的元素留出足够的空间。
答案 2 :(得分:1)
只需将普通的std::transform
与begin
和end
迭代器一起使用。不需要std::back_inserter
甚至不需要std::inserter
。
例如,std::array
不支持push_back
方法,但是std::transform
可以使用它:
#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> data = {1, 2, 3, 4, 5};
std::array<int, 5> arr{};
// note the lack of std::back_inserter just below
std::transform(data.cbegin(), data.cend(), arr.begin(),
[](auto i) {
return i * i;
});
for (const auto i : arr) {
std::cout << i << ' '; // prints 1, 4, 9, 16, 25
}
}