reusing objects after std::vector.emplace

116 views
Skip to first unread message

Ralf Fassel

unread,
Sep 23, 2015, 8:30:19 AM9/23/15
to

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

unread,
Sep 23, 2015, 2:40:20 PM9/23/15
to

On 2015-09-23 15:27, Ralf Fassel wrote:
>
> 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?
>


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

Öö Tiib

unread,
Sep 23, 2015, 2:40:20 PM9/23/15
to

On Wednesday, 23 September 2015 15:30:19 UTC+3, Ralf Fassel wrote:
> 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:

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).

>
> #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.
Reply all
Reply to author
Forward
0 new messages