相关疑难解决方法(0)

std :: vector :: swap会使迭代器失效吗?

如果我交换两个向量,它们的迭代器是否仍然有效,现在只是指向"其他"容器,或者迭代器是否会失效?

那是,给定:

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++ iterator stl visual-c++

39
推荐指数
2
解决办法
4079
查看次数

C++的默认拷贝构造函数本质上是不安全的吗?迭代器根本上也不安全吗?

我曾经认为,当遵循最佳实践时,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)!

这令我惊讶.我以前从未遇到过这个问题,我也不知道有什么优雅的方法来解决它.关于它的思考多一点,在我看来,那拷贝构造是默认不安全的 -事实上,在我看来那类应该不会是在默认情况下拷贝,但因为他们的实例变量之间的任何一种耦合的风险再现默认副本- 构造函数无效.

迭代器是否从根本上说不安全?或者,默认情况下类是否真的不可复制?

我在下面想到的解决方案都是不可取的,因为它们不会让我利用自动生成的复制构造函数:

  1. 为我编写的每个重要类手动实现一个拷贝构造函数.这不仅容易出错,而且对于编写复杂的类也很痛苦.
  2. 永远不要将迭代器存储为成员变量.这似乎是严重的限制.
  3. 默认情况下,对我写的所有类禁用复制,除非我能明确证明它们是正确的.这似乎完全违背了C++的设计,这对于大多数类型来说都具有值语义,因此是可复制的.

这是一个众所周知的问题,如果是这样,它是否有优雅/惯用的解决方案?

c++ iterator copy-constructor default-copy-constructor

36
推荐指数
6
解决办法
2544
查看次数

我保证在向量移动后指向std :: vector元素的指针是有效的吗?

考虑这个例子:

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?我无法在互联网上找到这些信息,也无法在标准本身上找到这些信息.

c++ stl move vector c++11

22
推荐指数
1
解决办法
1453
查看次数

std :: move()是否使迭代器无效?

考虑以下程序:

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,或者移动构造函数/赋值使所有迭代器无效?

c++ iterator undefined-behavior move-semantics c++11

9
推荐指数
2
解决办法
1201
查看次数

是通过移动保留std :: vector :: data()吗?

可能重复:
移动向量是否会使迭代器失效?

请考虑以下代码:

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吗?

c++ stdvector language-lawyer move-semantics c++11

6
推荐指数
1
解决办法
453
查看次数