【问题标题】:Using make_move_iterator, expected results使用 make_move_iterator,预期结果
【发布时间】:2020-08-03 01:56:11
【问题描述】:

我对@9​​87654323@ 有疑问。首先在f2() 中使用make_move_iterator 时,类似于Stroustrup C++ 4th Ed Page 964,它不会编译。有谁知道这是否正确使用以及为什么它不会编译?

另外,在其他示例中,我希望将数据移出源向量,但结果显示它仍然存在。这是预期的吗?

#include <iterator>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

void f0()
{
    // Use constructor method
    vector<int> v {0, 1, 2, 3};
    vector<int> v2 {make_move_iterator(v.begin()),
                    make_move_iterator(v.end())};
    cout << endl << "f0: v orig (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f0: v2 copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, ","));
    cout << endl;
}

void f1()
{
    vector<int> v {0, 1, 2, 3};
    vector<int> v2;

    // Use copy method
    copy(make_move_iterator(v.begin()), make_move_iterator(v.end()),
         back_inserter(v2));
    cout << "f1: orig output (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: end copy output" << endl;
}

void f2()
{    
   vector<int> v {0, 1, 2, 3};
   vector<int> v2;
// will not compile, example in Stroustrup C++ 4th Ed Page 964
//   copy(v.begin(), v.end(), make_move_iterator(back_inserter(v2)));
}


void f3()
{
    vector<int> v {0, 1, 2, 3};
    vector<int> v2(v.size());

    // Use copy method
    copy(make_move_iterator(v.begin()), make_move_iterator(v.end()),
         v2.begin());
    cout << "f1: orig output (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: end copy output" << endl;
}

int main()
{
    f0(); f1(); f2(); f3();
    return 0;
}

编译及结果:

clang++ -std=c++11 -pedantic -Wall test235.cc && ./a.out

f0: v orig (should be moved from)
0,1,2,3,
f0: v2 copy output
0,1,2,3,
f1: orig output (should be moved from)
0,1,2,3,
f1: copy output
0,1,2,3,
f1: end copy output
f3: orig output (should be moved from)
0,1,2,3,
f3: copy output
0,1,2,3,
f3: end copy output

Compilation finished at Sun Aug  2 21:47:27

【问题讨论】:

  • 一次只回答一个问题;您的第二个问题是 C++ move iterator and int vector 的精确副本,并由 copy vs std::move for ints 有效回答,所以请只回答第一个问题。
  • 为什么你认为它不会编译?
  • make_move_iterator 要求其参数的类型满足 LegacyInputIterator。而back_inserter 产生一个输出迭代器。尝试使目标移动是没有任何意义的——它是移动的来源,需要移动。
  • “我预计数据会从源向量中移出” 您究竟希望这一事实如何表现出来?你打算如何证明它发生或没有发生?在任何情况下,对于普通的ints,移动的行为与复制相同。

标签: c++


【解决方案1】:

要查看 make_move_iterator() 移动元素,您不能使用整数向量。必须将源迭代器传递给make_move_iterator,而不是目标。相反,我使用以下代码来显示移动迭代器的工作。

#include <iterator>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct X {
    int i;
    X(int ii) : i{ii} {}
    X(const X& x) : i{x.i} {} 
    X(X&& x) : i{x.i} {x.i = 0;}
    X& operator=(const X& x)
        {X tmp{x}; swap(*this, tmp); return *this;}
    X& operator=(X&& x) {swap(i, x.i); return *this;}
};
ostream& operator<<(ostream& os, const X& b)
{
    return os << b.i;
}

void f0()
{
    // Use constructor method
    vector<X> v {X(0), X(1), X(2)};
    vector<X> v2 {make_move_iterator(v.begin()),
                  make_move_iterator(v.end())};
    cout << endl << "f0: v orig (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<X>(cout, ","));
    cout << endl << "f0: v2 copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<X>(cout, ","));
    cout << endl;
}

void f1()
{
    vector<X> v {X(0), X(1), X(2)};
    vector<X> v2;
    copy(make_move_iterator(v.begin()),
         make_move_iterator(v.end()), back_inserter(v2));
    cout << endl << "f1: v orig (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<X>(cout, ","));
    cout << endl << "f1: v2 copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<X>(cout, ","));
    cout << endl;
}

int main()
{
    f0(); f1();
    return 0;
}

带编译输出:

clang++ -std=c++11 -pedantic -Wall test235.cc && ./a.out

f0: v orig (should be moved from)
0,0,0,
f0: v2 copy output
0,1,2,

f1: v orig (should be moved from)
0,0,0,
f1: v2 copy output
0,1,2,

【讨论】:

    猜你喜欢
    • 2021-01-05
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多