3参数形式list::splice()将单个元素从一个列表移动到另一个列表. SGI的文档明确声明所有迭代器,包括指向要移动的元素的迭代器仍然有效. Roguewave的文档没有说明splice()方法的迭代器失效属性,而C++标准明确声明它使所有迭代器和对被拼接元素的引用无效.
splicing()在实践中按照SGI的定义工作,但是我在微软的STL实现的调试/安全SCL版本中得到断言失败(解除引用无效迭代器)(严格遵循标准的字母).
现在,我正在使用list完全是因为我想在列表之间移动一个元素,同时保留指向它的迭代器的有效性.该标准对最初的SGI规范进行了极为无益的改变.
我该如何解决这个问题?或者我应该是务实,在沙把头(因为拼接并没有在实践中迭代器失效-甚至在MS的执行,一旦调试迭代器关闭).
假设我正在迭代Java中的Map ...我不清楚在迭代过程中我能对Map进行什么操作.我想我在Javadoc中对Iterator接口删除方法的这个警告大多感到困惑:
[...]如果在迭代正在进行中以除调用此方法之外的任何方式修改基础集合,则未指定迭代器的行为.
我确信我可以毫无问题地调用remove方法.但是在迭代Map集合时,我可以:
使用Map类put方法更改与键关联的值(使用现有键放置)?
使用Map类put方法添加一个新条目(使用新密钥放置)?
使用Map类删除方法删除条目?
我的猜测是我可以安全地做#1(放到现有密钥)但不安全做#2或#3.
提前感谢您对此的任何澄清.
使用迭代器循环STL映射与向量之间的性能差异是什么?我想使用map键进行插入,删除和一些访问,但我还需要定期访问map中的每个元素.
我有一个User类,其中包含一个String用户名.我有一个用户列表,我试图在表中使用
<s:iterator value="users" id="list">
<tr>
<td><s:property value="#list.username" /></td>
<td></td>
<td></td>
<td></td>
</tr>
</s:iterator>
Run Code Online (Sandbox Code Playgroud)
行正在显示正确的次数,因此它正在迭代我的列表.但是,我不知道如何访问username属性来显示它.显然我上面所说的不正确......有什么想法吗?
我想知道使std::list<>::splice引用新子容器中的子序列的迭代器无效的原因是什么.这看起来有点不合逻辑,特别是在标准std::container::swap规格方面.根据语言标准std::container::swap 不会使任何迭代器无效.这是一个非常合理的实用规范.但是,我会说这std::list<>::splice也会从保留迭代器的行为中获益匪浅.
我理解可能存在基于迭代器可达性等概念的纯粹学术考虑.但同时splice也是一种std::list特定的操作,这意味着为它提供定制的规范可能不会对其造成严重的概念损害.一般的STL设计.
那是什么?它会使一些std::list我认识不到的实际实施变得非法或过于复杂吗?
受这个问题的启发,询问如何将一个向量附加到自身,我的第一个想法是以下(是的,我意识到insert现在是一个更好的选择):
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<int> vec {1, 2, 3};
std::copy (std::begin (vec), std::end (vec), std::back_inserter (vec));
for (const auto &v : vec)
std::cout << v << ' ';
}
Run Code Online (Sandbox Code Playgroud)
但是,这打印:
1 2 3 1 * 3
Run Code Online (Sandbox Code Playgroud)
每次运行程序时*都是不同的数字.只有2被替换的事实是特殊的,如果真的有解释,我会有兴趣听到它.继续,如果我附加到不同的向量(原始副本),它会正确输出.如果我在前一行之前添加以下行,它也会正确输出copy:
vec.reserve (2 * vec.size());
Run Code Online (Sandbox Code Playgroud)
std::back_inserter尽管事先没有预留内存,但我认为这是一种将元素添加到容器末端的安全方法.如果我的理解是正确的,复制线有什么问题?
我假设它与编译器无关,但我使用的是GCC 4.7.1.
int *arr = (int*) malloc(100*sizeof(int));
int *arr_copy = (int*) malloc(100*sizeof(int));
srand(123456789L);
for( int i = 0; i < 100; i++) {
arr[i] = rand();
arr_copy[i] = arr[i];
}
// ------ do stuff with arr ------
// reset arr...
std::copy(arr_copy, arr_copy+100, arr);
Run Code Online (Sandbox Code Playgroud)
在编译时,我得到以下警告std::copy():
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2227):
warning C4996: 'std::_Copy_impl': Function call with parameters that may be
unsafe - this call relies on the caller to check that the passed values are
correct. To disable this warning, …Run Code Online (Sandbox Code Playgroud) 为什么这个代码
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.reserve(v.size() * 2); // Reserve enough space to keep iterators valid
std::copy(v.begin(), v.end(), std::back_inserter(v));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给我调试断言失败,Expression:vector iterators不兼容(Visual C++ 2008)?
我试图理解迭代器.我注意到Python文档认为迭代器是一个功能样式的构造.我真的不明白.
迭代器里面有一个状态是不是真的.所以当你调用时it.__next__(),你会改变迭代器的状态.据我所知,对象的变异状态不被认为是功能性的,因为函数式编程强调对象/闭包的不变性和组合能力.
实际上,问题出现了,因为我想编写一个Scheme过程/函数,它接受令牌并返回一个迭代器.
(define tokens->iterator
(lambda ls
(lambda ()
(if (null? ls)
'*eoi*
(let ((tok (car ls)))
(set! ls (cdr ls))
tok)))))
Run Code Online (Sandbox Code Playgroud)
请注意我必须使用set!变异ls,这就是我提出这个问题的方法.
要使用它,
(define it (tokens->iterator 1 '+ 2))
Run Code Online (Sandbox Code Playgroud)
要测试它,
scheme@(guile-user)> (it)
$2 = 1
scheme@(guile-user)> (it)
$3 = +
scheme@(guile-user)> (it)
$4 = 2
scheme@(guile-user)> (it)
$5 = *eoi*
scheme@(guile-user)> (it)
$6 = *eoi*
Run Code Online (Sandbox Code Playgroud)
只是为了好玩,我还将其翻译成Python:
def tokens_to_iterator(*tup):
ls = list(tup)
def iterator():
if not ls:
return "*eoi*"
else:
tok = …Run Code Online (Sandbox Code Playgroud) #include <vector>
#include <iostream>
#include <range/v3/all.hpp>
int main()
{
auto coll = std::vector{ 1, 2, 3 };
ranges::copy(
coll,
ranges::ostream_iterator<int>{ std::cout, ", " }
); // ok
ranges::copy(
coll,
std::ostream_iterator<int>{ std::cout, ", " }
); // error
}
Run Code Online (Sandbox Code Playgroud)
问题显示在上面的代码中.我使用range-v3-0.3.7.
对我来说,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求即可.
如果是这样,为什么范围的算法不与std的迭代器兼容?
iterator ×10
c++ ×7
stl ×4
algorithm ×1
c++-concepts ×1
c++20 ×1
containers ×1
invalidation ×1
java ×1
list ×1
map ×1
performance ×1
python ×1
range-v3 ×1
scheme ×1
struts2 ×1
vector ×1
visual-c++ ×1