vector<string> v = {"AAAAidad", "bbbb", "ADWHIBQSDS", "Hi", "fes", "dafegrg", "QQEEQEQEQEQ
E", "\"", "a"};
transform1(v.begin(), v.end(), back_inserter(v),
[] (string s) -> string{
for(char& c:s)
{
c = toupper(c);
}
return s;
});
使用上面的代码片段,我希望在v的末尾插入大写的字符串元素。 实际上,我只是得到以下输出
v = {"AAAAidad", "bbbb", "ADWHIBQSDS", "Hi", "fes", "dafegrg", "QQEEQEQEQEQ", "AAAAIDAD"}
只有第一个字符串被大写并插入。 向量中的其余字符串元素在哪里?
答案 0 :(得分:5)
当您分配到back_insert_iterator
时,它会在底层容器上调用push_back
。
在向量上调用push_back
至少会使end
迭代器失效,并可能使其他所有迭代器失效。
传递到transform
的开始和结束迭代器可以在遍历期间的任何时候失效,此时整个事物都会显示未定义的行为。
这是一个没有UB的版本,并且不需要自定义转换功能:
const auto original_size = v.size();
// add original_size empty strings at the end
v.resize(original_size * 2);
// the first new empty string is also one-past-the end of the originals
auto first_empty = v.begin() + original_size;
transform(v.begin(), first_empty, first_empty, strtoupper);
其中strtoupper
是您的原始lambda,或者,您可以重新使用transform:
std::string strtoupper(std::string s) {
transform(s.begin(), s.end(), s.begin(), toupper);
return s;
}
答案 1 :(得分:0)
@Useless也许你是对的,我使用自定义的transform1来解决它。而这次我没有使用缓存的结束迭代器。 谢谢!
20 template<class Input, class OutputIt, class UnaryOperation>
21 OutputIt transform1(Input input, OutputIt d_first, UnaryOperation unary_op)
22 {
23 auto first1 = input.begin();
24 while(first1 != input.end())
25 {
26 *d_first++ = unary_op(*first1++);
27 }
28 return d_first;
29 }