如果容器具有字符串类型的数据,则可以使用
std::move_iterator
将数据从源容器移动到目标容器。 std::move_iterator
不与容器中的其他数据类型一起操作。
std::move_iterator 工作正常
#include <iostream> // std::cout
#include <iterator> // std::move_iterator
#include <vector> // std::vector
#include <string> // std::string
#include <algorithm> // std::copy
using namespace std;
int main () {
vector<string>src = {"one", "two", "three", "four"}, des(4);
using Iter = vector<string>::iterator;
//move the data from src to des
move_iterator<Iter>beginitr(src.begin());
move_iterator<Iter>enditr(src.end());
Iter diter = des.begin();
while(beginitr != enditr)
{
*diter++ = *beginitr++;
}
cout << "src container size: " << src.size() << endl;
cout << "data: " ;
for_each(begin(src),end(src), [](string x){cout << x ;});
cout << endl << "THE END";
return 0;
}
输出
src container size: 4
data:
THE END
std::move_iterator 不移动数据
#include <iostream> // std::cout
#include <iterator> // std::move_iterator
#include <list> // std::vector
#include <string> // std::string
#include <algorithm> // std::copy
using namespace std;
int main () {
list<int>src = {1,2,3,4}, des(4);
using Iter = list<int>::iterator;
//move the data from src to des
move_iterator<Iter>beginitr = make_move_iterator(src.begin());
move_iterator<Iter>enditr = make_move_iterator(src.end());
Iter diter = des.begin();
while(beginitr != enditr)
{
*diter++ = *beginitr++;
}
cout << "src container size: " << src.size() << endl;
for_each(begin(src),end(src), [](int x){cout << x << endl;});
return 0;
}
输出
src container size: 4
1
2
3
4
看起来整数数据被复制到目标容器而不是被移动。
使用移动迭代器的唯一区别是取消引用迭代器会产生右值引用。如果只有复制赋值运算符可用,但没有移动赋值运算符,则这将用作“后备”。
以下代码演示了这一点:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
#include <utility>
struct Test
{
#if 0
Test(Test&&)
{
std::cout << "Test::Test(Test&&)\n";
}
Test& operator=(Test&&)
{
std::cout << "Test& Test::operator=(Test&&)\n";
return *this;
}
#endif
Test(Test const&)
{
std::cout << "Test::Test(Test const&)\n";
}
Test& operator=(Test const&)
{
std::cout << "Test& Test::operator=(Test const&)\n";
return *this;
}
Test()
{
std::cout << "Test::Test()\n";
}
};
int main() {
std::list<Test> src(4);
std::list<Test> des(4);
std::cout << "-------------------copy with move iterator--------------------\n";
std::copy(std::make_move_iterator(src.begin()), std::make_move_iterator(src.end()), des.begin());
std::cout << "-------------------copy with normal iterator--------------------\n";
std::copy(src.begin(), src.end(), des.begin());
}
输出
#if 0
保持原样:
...
-------------------copy with move iterator--------------------
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
-------------------copy with normal iterator--------------------
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
定义了移动语义的输出(
#if 1
而不是#if 0
):
...
-------------------copy with move iterator--------------------
Test& Test::operator=(Test&&)
Test& Test::operator=(Test&&)
Test& Test::operator=(Test&&)
Test& Test::operator=(Test&&)
-------------------copy with normal iterator--------------------
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
Test& Test::operator=(Test const&)
对于像
int
这样的算术类型,只有复制语义,没有移动语义,不会在代码中修改源列表。