如果我交换两个向量,它们的迭代器是否仍然有效,现在只是指向"其他"容器,或者迭代器是否会失效?
那是,给定:
using namespace std;
vector<int> x(42, 42);
vector<int> y;
vector<int>::iterator a = x.begin();
vector<int>::iterator b = x.end();
x.swap(y);
// a and b still valid? Pointing to x or y?
Run Code Online (Sandbox Code Playgroud)
似乎std没有提到这个:
[n3092 - 23.3.6.2]
void swap(vector<T,Allocator>& x);效果:将*的内容和容量()与x的内容和容量()进行交换.
请注意,因为我在VS 2005上,我也对迭代器调试检查等的影响感兴趣(_SECURE_SCL)
我曾经认为,当遵循最佳实践时,C++的对象模型非常强大.
就在几分钟前,我意识到我以前没有过.
考虑以下代码:
class Foo
{
std::set<size_t> set;
std::vector<std::set<size_t>::iterator> vector;
// ...
// (assume every method ensures p always points to a valid element of s)
};
Run Code Online (Sandbox Code Playgroud)
我写了这样的代码.直到今天,我还没有看到它的问题.
但是,考虑到它更多,我意识到这个类非常破碎:
它的copy-constructor和copy-assignment 复制里面的迭代器vector,这意味着它们仍然会指向旧的 set!毕竟新的不是真正的副本!
换句话说,我必须手动实现copy-constructor,即使这个类没有管理任何资源(没有RAII)!
这令我惊讶.我以前从未遇到过这个问题,我也不知道有什么优雅的方法来解决它.关于它的思考多一点,在我看来,那拷贝构造是默认不安全的 -事实上,在我看来那类应该不会是在默认情况下拷贝,但因为他们的实例变量之间的任何一种耦合的风险再现默认副本- 构造函数无效.
迭代器是否从根本上说不安全?或者,默认情况下类是否真的不可复制?
我在下面想到的解决方案都是不可取的,因为它们不会让我利用自动生成的复制构造函数:
考虑这个例子:
std::vector<int> v1 = { 1, 2, 3 };
const int* i = &v1[1];
std::vector<int> v2(std::move(v1));
std::cout << *i << std::endl;
Run Code Online (Sandbox Code Playgroud)
尽管在许多STL实现中这可能会起作用,但是我可以通过标准保证在std::vector移动a时不执行重新分配,并且内部缓冲区支持v2与以前的内部缓冲区支持相同v1?我无法在互联网上找到这些信息,也无法在标准本身上找到这些信息.
考虑以下程序:
struct list_wrapper
{
std::vector<int> m_list;
};
int main()
{
std::vector<int> myList { 1, 1, 2, 3, 5 };
const std::vector<int>::iterator iter = myList.begin();
list_wrapper wrappedList;
wrappedList.m_list = std::move(myList);
// Can I still dereference iter?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在调用之后std::move(myList),iter现在指向内部的有效项wrappedList.m_list,或者移动构造函数/赋值使所有迭代器无效?
可能重复:
移动向量是否会使迭代器失效?
请考虑以下代码:
std::vector<T> prepare(T*& data) {
std::vector<T> buffer;
// Fill in buffer.
data = buffer.data();
return buffer;
}
...
T* data;
auto vec = prepare(data);
// line 12
Run Code Online (Sandbox Code Playgroud)
vec.data() != data第12行可能吗?同样的,
std::vector<T> buffer;
// ... Fill in buffer ...
T* data = buffer.data();
auto vec = std::move(buffer);
// line 5
Run Code Online (Sandbox Code Playgroud)
vec.data() != data第5行有可能吗?
实际上两者都不可能在libstdc ++和libc ++的实现中,因为移动构造函数实现为简单的指针赋值,但似乎标准没有在其上指定任何内容(类似于移动std时需要保留的容量: :矢量?)."不变的复杂性"可以保证vec.data() == data吗?