f



reusing objects after std::vector.emplace

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! ]

0
Ralf
9/23/2015 7:27:48 AM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

2 Replies
433 Views

Similar Articles

[PageSpeed] 55

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.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
ISO
9/23/2015 1:34:17 PM
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


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Bo
9/23/2015 1:34:25 PM
Reply: