c++ - std::string and move_iterator -
i writing tokenizer split string
, put each of fields inside vector
. idea use string::find
repeatedly. instead of using temporary string
object, used move_iterator
s, supposed original string see characters stolen algorithm processed it. didn't happen.
this example code demonstrates i'm talking about:
#include <vector> #include <string> #include <iostream> using namespace std; void print_strings ( const vector<string> & v ) { unsigned int = 1; ( const auto & s : v ) cout << "#" << i++ << "\t: \"" << s << "\"" << endl; return; } int main ( void ) { string base( "hello, example string, icescreams" ); /* vector populate strings */ vector<string> v; /* 1: copy of 'base' */ v.emplace_back( base ); /* 2: copy of 'base' using iterators */ v.emplace_back( base.begin() , base.end() ); /* 3: string think _should_ move 'base' */ v.emplace_back( make_move_iterator(base.begin()) , make_move_iterator(base.end()) ); /* print strings twice * can see if has changed. */ print_strings( v ); print_strings( v ); return 0; }
when compiled g++ -std=c++11 -wall -wextra -werror -o2
, shows no warnings.
my guessings string
's constructors, in range version, copies specified range. i'm not sure, i'd sure and, of course, see workarounds had used.
best regards, kalrish
iterators don't know container.
a move_iterator
can't magically move string. can't move underlying element, that's single char
, moving char same copying it. need use std::move(base)
.
#include <vector> #include <string> #include <iostream> using namespace std; void print_strings ( const vector<string> & v ) { unsigned int = 1; ( const auto & s : v ) cout << "#" << i++ << "\t: \"" << s << "\"" << endl; return; } int main ( void ) { string base( "hello, example string, icescreams" ); /* vector populate strings */ vector<string> v; /* 1: copy of 'base' */ v.emplace_back( base ); /* 2: copy of 'base' using iterators */ v.emplace_back( base.begin() , base.end() ); /* 3: string think _should_ move 'base' */ std::cout << base << '\n'; // base still untouched here v.emplace_back( std::move(base) ); // it'll moved print_strings( v ); std::cout << "base: " << base << "/base\n"; // base empty return 0; }
see live here.
Comments
Post a Comment