c ++ - std :: string和move_iterator

时间:2013-08-23 16:32:28

标签: c++ string c++11 iterator move-semantics

我正在编写一个将string拆分并将每个字段放在vector内的标记生成器。我的想法是反复使用string::find。我没有使用临时string对象,而是使用了move_iterator,因为我认为原始字符串会在算法处理它时看到它的字符被盗。但它没有发生。

这是一个示例代码,演示了我在说什么:

#include <vector>
#include <string>
#include <iostream>

using namespace std;

void
print_strings
    ( const vector<string> & v )
{
    unsigned int i = 1;
    for ( const auto & s : v )
        cout << "#" << i++ << "\t: \"" << s << "\"" << endl;
    return;
}

int
main
    ( void )
{
    string base( "hello, this is an example string, I like icescreams" );

    /* Vector to populate with strings */
    vector<string> v;

    /* 1: a copy of 'base' */
    v.emplace_back( base );
    /* 2: a copy of 'base' using iterators */
    v.emplace_back( base.begin() , base.end() );
    /* 3: a string that I think _should_ move from 'base' */
    v.emplace_back( make_move_iterator(base.begin()) , make_move_iterator(base.end()) );

    /* Print the strings twice so that we
     * can see if something has changed. */
    print_strings( v );
    print_strings( v );

    return 0;
}

使用g++ -std=c++11 -Wall -Wextra -Werror -O2进行编译时,不会显示任何警告。

我的猜测是string范围版本的构造函数始终从指定范围复制。我不确定,我想确定,当然,看看你使用过的任何变通方法。

祝你好运, Kalrish

1 个答案:

答案 0 :(得分:0)

迭代器对容器一无所知。

move_iterator无法从字符串中神奇地移动。它不仅可以从其底层元素移动,也就是单个char,并且从char移动与复制它相同。您需要使用std::move(base)

#include <vector>
#include <string>
#include <iostream>

using namespace std;

void
print_strings
    ( const vector<string> & v )
{
    unsigned int i = 1;
    for ( const auto & s : v )
        cout << "#" << i++ << "\t: \"" << s << "\"" << endl;
    return;
}

int
main
    ( void )
{
    string base( "hello, this is an example string, I like icescreams" );

    /* Vector to populate with strings */
    vector<string> v;

    /* 1: a copy of 'base' */
    v.emplace_back( base );
    /* 2: a copy of 'base' using iterators */
    v.emplace_back( base.begin() , base.end() );
    /* 3: a string that I think _should_ move from 'base' */

    std::cout << base << '\n'; // base is still untouched here

    v.emplace_back( std::move(base) ); // now it'll be moved from

    print_strings( v );
    std::cout << "base: " << base << "/base\n"; // base is empty
    return 0;
}

直播here