注意:这不是我应该"使用list还是deque"的问题.这是一个关于迭代器在面对的有效性的问题insert()
.
这可能是一个简单的问题,我只是太密集了,看不到正确的方法来做到这一点.我正在实现(无论好坏)网络流量缓冲区作为a std::list<char> buf
,并且我将当前的读取位置保持为迭代器readpos
.
当我添加数据时,我会做类似的事情
buf.insert(buf.end(), newdata.begin(), newdata.end());
Run Code Online (Sandbox Code Playgroud)
我现在的问题是,如何保持readpos
迭代器有效?如果它指向旧的中间buf
,那么它应该没问题(通过std :: list的迭代器保证),但通常我可能已经读取并处理了所有数据而且我有readpos == buf.end()
.在插入之后,我readpos
总是希望指向下一个未读的字符,在插入的情况下应该是第一个插入的字符.
有什么建议?(没有将缓冲区更改为a std::deque<char>
,这似乎更适合任务,如下所示.)
更新:从使用GCC4.4的快速测试中我发现deque和list的行为方式不同readpos = buf.end()
:插入结束后,readpos在列表中被破坏,但指向deque中的下一个元素.这是标准保证吗?
(根据cplusplus,任何deque :: insert()都会使所有迭代器失效.这没有用.可能使用计数器比迭代器更好地跟踪双端队列中的位置?)
在GCC中,std :: list的size()方法是O(n).为什么?
for the C++ 11 in the standard说list的size()应该是O(1) http://en.cppreference.com/w/cpp/container/list/size
但是在glibc中我们有以下内容:
/usr/include/c++/4.6.3/bits/stl_list.h
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class list : protected _List_base<_Tp, _Alloc>
{
...
size_type
size() const
{ return std::distance(begin(), end()); }
Run Code Online (Sandbox Code Playgroud)
问题是:如何在海湾合作委员会中实施一项为期三年的要求?
编辑:gcc 5改变了这一点:虽然以ABI变化为代价; 这意味着使用gcc 5.0编译的c ++代码不适用于旧版本的c ++运行时库.
来自https://gcc.gnu.org/gcc-5/changes.html "默认情况下启用std :: list的新实现,带有O(1)size()函数"
我有一些C代码,其中有两个链表(比如A和B),A在特定位置插入B,A仍然有元素.
如何使用C++ STL有效地模拟相同的行为?如果我尝试拼接,它会使第二个空.
谢谢,Gokul.
在C++ 0x中,我想要的是:
std::list<std::string> colours = {"red", "blue", "green", "grey", "pink", "violet"};
Run Code Online (Sandbox Code Playgroud)
标准的非0x C++中最简单的方法是什么?
C++ std :: list sort函数是否保证保留列表中相等元素的顺序?例如,如果我们在列表中有对象A,B和C并且比较运算符被重载,那么A == C和B <A,我们是否必须获得BAC或者是否可以获得BCA?
为什么第二次调用print_all
函数会导致静态语义错误?
#include <list>
using std::list;
class foo {
// ...
};
class bar : public foo {
// ...
};
static void print_all(list<foo*>& L) {
// ...
}
list<foo*> LF;
list<bar*> LB;
// ...
print_all(LF); // works fine
print_all(LB); // static semantic error
Run Code Online (Sandbox Code Playgroud) 考虑以下程序:
#include <list>
#include <cstdio>
int main() {
std::list<int> l;
std::list<int>::iterator it = l.begin();
l.push_back(0);
l.insert(it, 1);
for(const int &i: l) {
printf("%d", i);
}
}
Run Code Online (Sandbox Code Playgroud)
这打印01
. 非常令人惊讶。如果我将列表更改为双端队列,它会打印预期的.10
这是一个错误吗?
编辑:双端队列行为是不相关的,双端队列的迭代器被push_back无效。
我有一个虚假的问题.我总是读到C++ std::list
容器在开头,结尾和中间插入元素的时间是恒定的:哪个是直接在元素中间插入元素的正确方法std::list
?可能是这个吗?
std::list<int> l;
l.push_back(10);
l.push_back(20);
l.push_back(30);
l.push_back(40);
l.push_back(50);
l.push_back(60);
l.insert( l.end()- l.begin() /2 ); //? is this
// inserting directly in the middle?
Run Code Online (Sandbox Code Playgroud)
当我们说'插入中间'时,我们是否真的意味着我们保存线性时间从列表的开头到所需的点(逐个遍历所有链接的元素)?
说我有一个清单:
list<int> A { 1, 2, 3, 4};
我这样做:
A.remove(5);
这样做会返回什么?当我在 Visual Studio 中为此创建一个简单的程序时,它运行时不会出现任何错误,所以我假设它是一个法律声明。
但是,如果我想跟踪该元素是否被删除,并打印出它已被删除或该元素不存在怎么办?
例如,是否有这样的事情:
if (A.remove(5) == true) {
cout << "Element has been removed" << endl;
} else {
cout << "Element does not exist" << endl;
}
Run Code Online (Sandbox Code Playgroud)
如果在第一次调用remove()
函数之前存在,则无需遍历列表并将 5 与每个元素进行比较就可以完成?
例如,我试图找出如何反转,grades{1, 2, 3, 4, 5, 6}
从第三个元素开始。
我知道我们无法通过列表来(grades.begin() + 2)
获得该职位,但我不知道如何去做。这是我到目前为止所拥有的,我只是颠倒了整个列表:
reverse(firstList.begin(), firstList.end());
Run Code Online (Sandbox Code Playgroud)
我希望它是相反的,以便列表变成:grades{1, 2, 6, 5, 4, 3}