Home  >  Article  >  Backend Development  >  How does the Implicit Move Rule work when returning a named object by value in C ?

How does the Implicit Move Rule work when returning a named object by value in C ?

DDD
DDDOriginal
2024-11-04 06:20:02172browse

How does the Implicit Move Rule work when returning a named object by value in C  ?

Returning a Named Object of a Class by Value and the Implicit Move Rule

When returning an object of a class by value from a function, the implicit move rule comes into play. This rule governs the behavior of the compiler when constructing a temporary object to hold the returned value.

Example 1:

Consider the following code snippet:

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(const test& z) {
        printf("test(const test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>

Output:

test()
test(test&& s)

In this example, the function Some_thing returns a named object of the test class, constructed using the default constructor. Since the compiler can elide the copy due to the NRVO (named return value optimization), we see the output of the default constructor test() followed by the implicit move constructor test(test&& s).

Example 2:

Now, let's modify the Some_thing function to use the copy constructor instead.

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(test& z) {
        printf("test(test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");  // Deleted this constructor
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>

Output:

test()
test(test&z)

Surprisingly, this code also compiles and runs, even though there is no move constructor defined. This is because the implicit move rule checks whether the expression i is "move-eligible." In this case, i is a local variable, which is move-eligible. Therefore, the compiler can still elide the copy operation.

The Implicit Move Rule

The implicit move rule triggers when you return an object by value, and the following conditions are met:

  • The expression representing the returned value is move-eligible (i.e., it can be moved from without violating any aliasing rules).
  • No user-defined copy or move constructor/assignment operator is viable.

Conclusion

The implicit move rule provides an efficient and concise way to return objects by value. It helps optimize code, reduce unnecessary copying, and improve performance. However, it is essential to understand its limitations and be aware of the potential issues it may introduce when used without proper consideration.

The above is the detailed content of How does the Implicit Move Rule work when returning a named object by value in C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn