Discussion:
reusing objects after std::vector.emplace
(too old to reply)
Ralf Fassel
2015-09-23 13:27:48 UTC
Permalink
Having not understood completely and absolutely in all depth the concept
of rvalue references, I hope the following is not an FAQ...

My understanding was that after an move operation on an object, one
should not further deal with it:

#include <vector>
#include <string>
#include <sstream>

void split_string(const std::string & s, std::vector<std::string> & v) {
std::istringstream sstrm(s);

std::string str;
// here we're reusing str after the emplace_back, is this ok?
while(sstrm >> str) v.emplace_back(str);
}

Should this loop better be

while (1) {
std::string str;
if (!(sstrm >> str)) break;
v.emplace_back(str);
}

Somehow I feel that the >> operator in the first example could do
nothing worse than the DTOR in the second, so both should be ok?

TNX
R'
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Bo Persson
2015-09-23 19:34:25 UTC
Permalink
Post by Ralf Fassel
Having not understood completely and absolutely in all depth the concept
of rvalue references, I hope the following is not an FAQ...
My understanding was that after an move operation on an object, one
#include <vector>
#include <string>
#include <sstream>
void split_string(const std::string & s, std::vector<std::string> & v) {
std::istringstream sstrm(s);
std::string str;
// here we're reusing str after the emplace_back, is this ok?
while(sstrm >> str) v.emplace_back(str);
}
Should this loop better be
while (1) {
std::string str;
if (!(sstrm >> str)) break;
v.emplace_back(str);
}
Somehow I feel that the >> operator in the first example could do
nothing worse than the DTOR in the second, so both should be ok?
The original code is ok. The moved from string is defined to be in a
consistent state and can be assigned a new value.


Bo Persson
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Öö Tiib
2015-09-23 19:34:17 UTC
Permalink
Post by Ralf Fassel
Having not understood completely and absolutely in all depth the concept
of rvalue references, I hope the following is not an FAQ...
My understanding was that after an move operation on an object, one
No. All objects of classes in standard library must remain in valid state
after move. For most classes that state is unspecified but no limits to
further usage. For some classes however it is specified (like 'unique_ptr'
must be empty after move).
Post by Ralf Fassel
#include <vector>
#include <string>
#include <sstream>
void split_string(const std::string & s, std::vector<std::string> & v) {
std::istringstream sstrm(s);
std::string str;
// here we're reusing str after the emplace_back, is this ok?
while(sstrm >> str) v.emplace_back(str);
}
Here are no move done at all. It is perfect forwarding so a
copy constructor is called by 'std::allocator_traits::construct'
to emplace 'str' to 'v'. Should be something like:

while(sstrm >> str) v.emplace_back(std::move(str));

It must be ok, since 'operator>>' there is documented to
overwrite the unspecified state that 'str' has after move.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Loading...