1

I know if you use std::move(s), then the s can not use again, But I have some questions.

If I don't do move constructor/assignment operator, Does the variable still exist?

// not do assignment
void test2(string &&t) {
    return;
}

void test1(string &&s) {
    test2(std::move(s));
}

int main()
{
    string s("123");
    
    test1(std::move(s));
    cout << "s: " << s << endl;
}

Above test seems it exist, So is this the best practice to use std::move in a while loop below.

// do assignment
bool test4(string &&t) {
    if (condition) {
        return false;
    }
    
    string m = std::move(t);
    
    return true;
}

void test3(string &&s) {
    while(true) {
        if( test4(std::move(s)) ) {
            break;
        }
    }
}

seems if you don't do move assignment operator the s is still exist next loop, when it success then it do move assignment operator and break the loop, There seems to be no logical error, but I want to know if this is the best practice ? Because you need to handle data carefully.

daohu527
  • 452
  • 4
  • 15
  • 2
    You can absolutely use `s` again. The object will however be in an undefined state, so there are some things you should not do with it. – super Dec 15 '20 at 15:28
  • 3
    Something to bear in mind as you continue your career in C++ is that you should never trust the output of a program to mean that a certain behavior is guaranteed. – AndyG Dec 15 '20 at 15:29
  • What @AndyG means is learn about a certain condition (or more accurately, a behaviour) called [undefined behaviour](https://stackoverflow.com/questions/367633/what-are-all-the-common-undefined-behaviours-that-a-c-programmer-should-know-a) – kesarling He-Him Dec 15 '20 at 15:32
  • 6
    @super "undefined state" -> "unspecified state". – Bathsheba Dec 15 '20 at 15:34

1 Answers1

2

I know if you use std::move(s), then the s can not use again

That's not really true.

After an object of a standard library type has been moved-from, unless otherwise stated its state is "valid but unspecified", so indeed it's best not to use it again unless you know you've put it back into a useful state (e.g. .clear() on a vector). (If the object is of one of your own types, you define those rules.)

But std::move doesn't move anything. It only prepares your expression for triggering a move. If that didn't occur, then literally nothing happened, and you can keep using s without fear.

However, you will confuse readers of your code. If you're not passing the result of std::move(s) to a move constructor or move assignment operator, best not write it at all.

seems if you don't do move assignment operator the s is still exist next loop, when it success then it do move assignment operator and break the loop, There seems to be no logical error, but I want to know if this is the best practice ?

It's correct, but it's kind of hard to read and follow, so it might be best to find some clearer way to structure it.

Because you need to handle data carefully.

Indeed.


Ideally, both test1 and test2 would take const std::string& (since neither of them take ownership of the string), and then it will also be clear to the author of main that they needn't/shouldn't write std::move there: it would be harmless, but pointless.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • thx for your advice, but `Ideally, both test1 and test2 would take const std::string& (since neither of them take ownership of the string)` if I use an rvalue I need to `copy constructor`, if use rvalue reference then I use `move constructor `. If I don't want to use s again, because I already know what I do? – daohu527 Dec 15 '20 at 15:44
  • @dahohu527 Why? You're not moving from it. That's the crux of your question. – Asteroids With Wings Dec 15 '20 at 15:46
  • The ownership is the question, when I write some class like myString I really need to implement `move constructor ` – daohu527 Dec 15 '20 at 15:47
  • @dahohu527 I'm sorry, I don't really understand what you are asking me. – Asteroids With Wings Dec 15 '20 at 15:54
  • My question is why you suggest to `test1 and test2 would take const std::string&`, I use `rvalue reference` beacuse I want to do `move assignment` – daohu527 Dec 15 '20 at 16:07
  • 1
    @dahohu527 But you _don't_ do move assignment!! `test1` passes it on to `test2`, and `test2` does nothing. – Asteroids With Wings Dec 15 '20 at 16:22
  • it's just a testcase. Thank you for the explanation! – daohu527 Dec 16 '20 at 00:52