这是一个打算执行的功能:
a)接受int
的向量b)对于输入向量中的每个int,追加此int的反函数
前提条件:无
后置条件:返回向量的大小()是2 *输入向量的大小。
请注意,矢量已就地修改。
这个函数是否严格定义了变换期间迭代器失效的行为?
是否有更好/更简洁/更健壮的方式来编写它?
{{1}}
答案 0 :(得分:14)
只要不超过预分配容量,就不会发生重新分配,也不会使引用矢量项的引用或迭代器失效。但是,由于end()
返回的迭代器未引用任何向量项,因此它可能仍会失效。
23.3.11.3载体容量 [vector.capacity]
- ...在调用
醇>reserve()
之后发生的插入过程中不会发生重新分配,直到插入使向量的大小大于capacity()
...
23.3.11.5向量修饰语 [vector.modifiers]
- ...如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。
醇>
答案 1 :(得分:4)
关于迭代器失效规则的部分已经被涵盖了,所以我将借此机会谦虚地质疑是否需要使用所有这些机制(以其微妙的规则)来处理这样一个微不足道的问题。你也可以认为这是对
的刺激加成:
是否有更好/更简洁/更健壮的方式来编写它?
问题的一部分。
老实说,我完全用 Status({ input, meta: {touched, error}, ...custom }) {
const reduxFormOnChange = input.onChange;
// the signature for this onChange is specific to
// semantic-ui Select
const semanticSelectOnChange = (maybe, wrong, order, or, irrelevant) => {
// here we make the translation
// so that the Redux form onChange gets
// called correctly.
// (NOTE: this is an example, not actual code suggestion)
reduxFormOnChange(or, maybe);
};
return (
<Form.Field control={Select}
name="Status" label="Status"
options={status} placeholder="Status"
{...input} {...custom}
onChange={ semanticSelectOnChange }
/>
);
}
循环的先进技术来回避这个问题。 KISS!
for
并非所有内容都必须在深层的STL算法中进行混淆。这个更短,IMO更具可读性,并避免了关于迭代器失效的麻烦。
此外,除非编译器自上次检查以来已经获得了额外的智能,否则这要快得多,因为避免了std::vector<int> append_negatives(std::vector<int> v) {
size_t sz = v.size();
v.resize(sz*2);
for(size_t i = 0; i < sz; ++i) v[i+sz] = -v[i];
return v;
}
的所有开销(检查容量是否足够以及每次迭代时的增量大小),这将被替换直接指针访问(一个汇编指令);纤细而简单的环体为自动展开提供了更好的机会。我希望编译速度更快,因为我们避免实例化一堆模板。
请注意,即使使用push_back
benemoth,也可以获得速度优势/无失效头痛:
transform
但我没有看到这种过于冗长的代码优于普通std::vector<int> append_negatives(std::vector<int> v) {
size_t sz = v.size();
v.resize(sz * 2);
auto beg = begin(v);
std::transform(beg, beg + sz, beg + sz,
[](int x) { return -x; });
return v;
}
循环的任何优势,除非你通过&#34; cool&#34;您可以使用C ++功能来挤入代码。
@MikeMB询问默认构造成本高昂的类型;在这种情况下,明确的for
很好:
push_back
如果原始帖子中的std::vector<int> append_negatives(std::vector<int> v) {
size_t sz = v.size();
v.reserve(sz*2); // optional
for(size_t i = 0; i < sz; ++i) v.push_back(-v[i]);
return v;
}
有效,您还可以使用基于范围的for循环:
transform
方式在眼睛上比基于转换的解决方案更好,但我在评论中看到,对于结束迭代器失效仍然没有达成共识,所以这只是无效。