Questions tagged [copy-elision]

Copy elision refers to an exception to the as-if rule allowing to omit copies

Copy Elision is an exception to the as-if rule governing the behavior of C++ programs.

Return-value-optimization is copy-ellision applied to value-returns.

12.8 Copying and moving class objects [class.copy]

31 When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization.123
This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

  • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value
  • in a throw-expression, when the operand is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the exception object (15.1) can be omitted by constructing the automatic object directly into the exception object
  • when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
  • when the exception-declaration of an exception handler (Clause 15) declares an object of the same type (except for cv-qualification) as the exception object (15.1), the copy operation can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the exception-declaration.
272 questions
1
vote
0 answers

How does prvalue works?

I have read a few posts on SO about prvalue and guaranteed copy elision (especially this one). But I am still confused about how prvalue works. Consider the following code (C++17): class Y { public: Y() { cout << "Y dctor\n"; } }; class…
CPPL
  • 726
  • 1
  • 10
1
vote
1 answer

Can initializing an object with a prvalue function result call the move constructor?

I started with this piece of code to show the effects of NRVO: struct test_nrvo { bool b; long x[100]; // Too large to return in register }; test_nrvo tester(test_nrvo* p) { test_nrvo result{ p == &result }; return result; } bool…
Artyer
  • 31,034
  • 3
  • 47
  • 75
1
vote
1 answer

std::vector doesn't construct in place

I have this little test code to show what operations std::vector does on a class A for various operations. I'm a bit disappointed by how many copy operations are done. Update: I forgot a noexcept in the move constructor. fixed. std::initializer…
Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
1
vote
1 answer

gcc: invalid error "use of deleted function" (copy constructor)?

Simplified issue: #include class X { public: int a = 0; X() { printf("constr-def %d\n", a); } X(int i):a(i+1) { printf("constr-i %d\n", a); } int operator=(int i) { a = i; return i; } operator bool() { return !!a; } …
kxr
  • 4,841
  • 1
  • 49
  • 32
1
vote
1 answer

Why destructor is called if the return operation is elided?

I have the following code that mimics an elision testcase class Obj { public: int x = 0; Obj(int y) : x(y) {std::cout << "C\n"; } ~Obj() { std::cout << "D\n"; } }; auto factory() { std::vector vec {1,2,3}; std::cout<< &vec[0] <<…
Matteo Galeotti
  • 105
  • 1
  • 9
1
vote
1 answer

Copy elision and move constructor

Consider the following definition of Person: struct Person { Person() { std::cout << "construct, "; } Person(const Person&) { std::cout << "copy\n"; } Person(Person&&) { std::cout << "move\n"; } }; And 3 different functions to create a…
mfnx
  • 2,894
  • 1
  • 12
  • 28
1
vote
1 answer

Is 1-arg overload of variadic template function useful? Should it used a magic && reference? Is Copy-Elision taking place in this case?

I have an existing std::ostream-like type, which has several operator<< overloads for various types. Since that type is used as a const& argument to other APIs, I'm adding convenience factory-functions for easy inline use, at call sites. I wrote the…
ddevienne
  • 1,802
  • 2
  • 17
  • 28
1
vote
0 answers

Is move elision required in case of copy list initialization in C++20?

Please consider following C++20 program: #include struct A { A() {} A( const A& ) = delete; A( A&& ) { std::cout << "m "; } }; int main() { [[maybe_unused]] A a = {{A{}}}; } I expected that move elision is required here…
Fedor
  • 17,146
  • 13
  • 40
  • 131
1
vote
1 answer

Is copy elision mandatory (if allowed at all) in the ternary operator?

Please consider the following C++17 code: #include #include struct S { S(int) { std::cout << "S() "; } S(const S &) { std::cout << "S(const S &) "; } S(S &&) = delete; ~S() { std::cout << "~S() "; } }; int…
Fedor
  • 17,146
  • 13
  • 40
  • 131
1
vote
2 answers

Can I avoid copies when returning multiple values, while keeping my return type?

If we write the following function: auto foo() { Foo foo { /* ... */ }; do_stuff(foo); return foo; } then NRVO should kick in, so that foo does not get copied on return. Now suppose I want to return two different values: auto foo() { …
einpoklum
  • 118,144
  • 57
  • 340
  • 684
1
vote
2 answers

why move constructor being used instead of copy?

Why is move constructor being called instead of copy constructor? And when I remove move constructor ,then copy constructor is called . Used : -fno-elide-constructors to avoid copy elision #include class test { public: int x; char…
Lion's_Den
  • 121
  • 1
  • 7
1
vote
0 answers

Why is NRVO not performed here (mutiple returns)?

NRVO is not performed for MyString ret in the following method. The default constructed MyString (return {};) gets directly constructed into the target, ret is move constructed into the target. MyString MyString::Substring(size_type idx, size_type…
Ruperrrt
  • 489
  • 2
  • 13
1
vote
1 answer

Guaranteed copy elision for uniform braced array initialization - Shouldn't this be mandatory since C++17?

As far as I understand the new rules correctly https://en.cppreference.com/w/cpp/language/copy_elision http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html This code should compile for C++17 standard conform compilers struct…
Secundi
  • 1,150
  • 1
  • 4
  • 12
1
vote
0 answers

Is C++ compiler allowed to convert last usage of lvalue to rvalue implicitly?

According to C++ standard: Copy elision is one of the two allowed forms of optimization, alongside allocation elision and extension, (since C++14) And if I recall correctly, copy elision is only allowed in return, throw, catch, and yield…
Lifu Huang
  • 11,930
  • 14
  • 55
  • 77
1
vote
1 answer

Move assignment in overloaded vector summation

I am going over A Tour of C++ (Section 5.2 Copy and Move). Following the instructions in the book, I have built a container called Vector (it mimics std::vector). My goal is to efficiently implement the following (element-wise) summation: Vector r =…
iamvegan
  • 482
  • 4
  • 15