c++ - move_iterator 是做什么用的

标签 c++ c++11 iterator move

如果我理解正确,a=std::move(b) 将引用 a 绑定(bind)到 b 的地址。而且这个操作之后b指向的内容是不保证的。

move_iterator的实现here有这条线

auto operator[](difference_type n) const -> decltype(std::move(current[n]))
  { return std::move(current[n]); }

但是,我认为 std::move 数组中的元素没有意义。如果 a=std::move(b[n]) 会发生什么?

下面的例子也让我很困惑:

std::string concat = std::accumulate(
                             std::move_iterator<iter_t>(source.begin()),
                             std::move_iterator<iter_t>(source.end()),
                             std::string("1234"));

由于concat会自己分配一 block 连续的内存来存储结果,不会和source有任何重叠。 source 中的数据将被复制到 concat 但不会 move 。

最佳答案

If I understand it correct, a=std::move(b) binds reference a to the address of b. And after this operation the content that b points to is not guaranteed.

啊,不:a 不是必要 引用。 std::move 的上述使用还授予编译器调用 decltype(a)::operator=(decltype(b)&&) 的权限(如果存在):这样的分配在赋值给 a 的过程中使用运算符,不需要保留 b 的值,但仍必须将 b 留在 some 理智的破坏状态。

However, I don't think it makes sense to std::move an element in an array. What happens if a=std::move(b[n])?

这很有意义......它只是意味着每个数组元素可以有效地分配/move 到另一个变量,但每个元素只能分配一次。在它们被移出后,正确编写的 move 构造函数或赋值运算符应该使对象处于有效但未指定的状态,这意味着您通常需要在读取它们之前再次设置它们。

我的answer here展示了某人如何将元素从 list 附加/move 到 vector。使用当前的 C++ 标准,您可以像这样直接创建 move_iterators。

下面的代码展示了如何 - 即使使用较旧的编译器/C++ 标准 - make_move_iterator 如果你想从 std::copy源迭代器范围。

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

struct X
{
    X(int n) : n_(n) { }
    X(const X& rhs) : n_(rhs.n_) { }
    X(X&& rhs) : n_{ rhs.n_ } { rhs.n_ *= -1; std::cout << "=(X&&) "; }
    X& operator=(X&& rhs) { n_ = rhs.n_; rhs.n_ *= -1; std::cout << "=(X&&) "; return *this; }
    int n_;
};

int main()
{
    std::vector<X> v{2, 1, 8, 3, 4, 5, 6};
    std::vector<X> v2{};

    std::copy(v.begin() + 2, v.end(), std::insert_iterator(v2, v2.end()));
    for (auto& x : v)
        std::cout << x.n_ << ' ';
    std::cout << '\n';

    std::copy(std::make_move_iterator(v.begin() + 2), std::make_move_iterator(v.end()), std::insert_iterator(v2, v2.end()));
    for (auto& x : v)
        std::cout << x.n_ << ' ';
    std::cout << '\n';
}

输出:

2 1 8 3 4 5 6 
=(X&&) =(X&&) =(X&&) =(X&&) =(X&&) 2 1 -8 -3 -4 -5 -6 

代码可以在 coliru 上运行/编辑.

关于c++ - move_iterator 是做什么用的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28042979/

相关文章:

python - 为我的自定义迭代器实现 iteritems 函数?

c++ - C++ 类中的许多成员函数对性能有影响吗?

c++ - vector 析构函数导致程序在 C++ 中崩溃

c++ - 将子类对象作为异常抛出

迭代器的 C++ 模板特化

c++ - 实例化重载函数模板

c++ - 迭代结构列表

java - 在仍在使用时使用迭代器从 ArrayList 中删除内容

c++ - Hook LoadLibrary API 调用

c++ - C++11 的 LLVM 和 Clang 支持