Could a smart compiler do all the things std::move does without it being part of the language?

前端 未结 3 1725
难免孤独
难免孤独 2021-01-06 15:21

This is a bit theoretical question, but although I have some basic understanding of the std::move Im still not certain if it provides some additional functionality to the la

3条回答
  •  没有蜡笔的小新
    2021-01-06 15:57

    No.

    But tbh I guess nobody will use var x after doing std::move(x)

    Absolutely not guaranteed. In fact, a decent part of the reason why std::move(x) is not automatically usable by the compiler is because, well, it can't be decided automatically whether or not you intend this. It's explicitly well-defined behaviour.

    Also, removing rvalue references would imply that the compiler can automagically write all the move constructors for you. This is definitely not true. D has a similar scheme, but it's a complete failure, because there are numerous useful situations in which the compiler-generated "move constructor" won't work correctly, but you can't change it.

    It would also prevent perfect forwarding, which has other uses.

    The Committee make many stupid mistakes, but rvalue references is not one of them.

    Edit:

    Consider something like this:

    int main() {
        std::unique_ptr x = make_unique();
        some_func_that_takes_ownership(x);
        int input = 0;
        std::cin >> input;
        if (input == 0)
            some_other_func(x);
    }
    

    Owch. Now what? You can't magic the value of "input" to be known at compile-time. This is doubly a problem if the bodies of some_other_func and some_func_that_takes_ownership are unknown. This is Halting Problem- you can't prove that x is or is not used after some_func_that_takes_ownership.

    D fails. I promised an example. Basically, in D, "move" is "binary copy and don't destruct the old". Unfortunately, consider a class with, say, a pointer to itself- something you will find in most string classes, most node-based containers, in designs for std::function, boost::variant, and lots of other similar handy value types. The pointer to the internal buffer will be copied but oh noes! points to the old buffer, not the new one. Old buffer is deallocated - GG your program.

提交回复
热议问题