copy-elision

C++11 constructor argument: std::move and value or std::forward and rvalue reference

家住魔仙堡 提交于 2019-12-03 21:46:24
Which of the below two should be preferred and why? struct X { Y data_; explicit X(Y&& data): data_(std::forward<Y>(data)) {} }; vs struct X { Y data_; explicit X(Y data): data_(std::move(data)) {} }; The two variants differ in functionality. The following statements work for the second one–but not for the first one: Y y; X x(y); If you are looking for the same functionality, the two variants should look as follows: struct X { Y data_; explicit X(const Y& data) : data_(data) { } explicit X(Y&& data) : data_(std::move(data)) { } }; struct X { Y data_; explicit X(Y data) : data_(std::move(data))

initializing a non-copyable member (or other object) in-place from a factory function

两盒软妹~` 提交于 2019-12-03 09:27:08
问题 A class must have a valid copy or move constructor for any of this syntax to be legal: C x = factory(); C y( factory() ); C z{ factory() }; In C++03 it was fairly common to rely on copy elision to prevent the compiler from touching the copy constructor. Every class has a valid copy constructor signature regardless of whether a definition exists. In C++11 a non-copyable type should define C( C const & ) = delete; , rendering any reference to the function invalid regardless of use (same for non

Does the behavior of guaranteed copy elision depend on existence of user-defined copy constructor?

半世苍凉 提交于 2019-12-03 08:54:04
问题 The following code behaves differently with or without user-defined copy constructor under GCC 8.0.1: #include <cassert> struct S { int i; int *p; S() : i(0), p(&i) {} // S(const S &s) : i(s.i), p(&i) {} // #1 // S(const S &s) : i(s.i), p(s.p) {} // #2 // S(const S &s) = delete; // #3 }; S make_S() {return S{};} int main() { S s = make_S(); assert(s.p == &s.i); } With either of the commented user-defined copy constructors (even with #2, the one performing a simple shallow copy), the assertion

Exact moment of “return” in a C++-function

我是研究僧i 提交于 2019-12-03 05:23:41
问题 It seems like a silly question, but is the exact moment at which return xxx; is "executed" in a function unambiguously defined? Please see the following example to see what I mean (here live): #include <iostream> #include <string> #include <utility> //changes the value of the underlying buffer //when destructed class Writer{ public: std::string &s; Writer(std::string &s_):s(s_){} ~Writer(){ s+="B"; } }; std::string make_string_ok(){ std::string res("A"); Writer w(res); return res; } int main(

Copy constructor not called when initializing an object with return value of a function

半世苍凉 提交于 2019-12-03 03:03:29
Consider the following code: #include <iostream> using namespace std; class A { public: int a; A(): a(5) { cout << "Constructor\n"; } A(const A &b) { a = b.a; cout << "Copy Constructor\n"; } A fun(A a) { return a; } }; int main() { A a, c; A b = a.fun(c); return 0; } The output of the above code with g++ file.cpp is: Constructor Constructor Copy Constructor Copy Constructor The output of the above code with g++ -fno-elide-constructors file.cpp is: Constructor Constructor Copy Constructor Copy Constructor Copy Constructor I know Return Value Optimization. My question is which call to copy

initializing a non-copyable member (or other object) in-place from a factory function

▼魔方 西西 提交于 2019-12-03 00:00:00
A class must have a valid copy or move constructor for any of this syntax to be legal: C x = factory(); C y( factory() ); C z{ factory() }; In C++03 it was fairly common to rely on copy elision to prevent the compiler from touching the copy constructor. Every class has a valid copy constructor signature regardless of whether a definition exists. In C++11 a non-copyable type should define C( C const & ) = delete; , rendering any reference to the function invalid regardless of use (same for non-moveable). (C++11 §8.4.3/2). GCC, for one, will complain when trying to return such an object by value

Does the behavior of guaranteed copy elision depend on existence of user-defined copy constructor?

醉酒当歌 提交于 2019-12-02 22:52:13
The following code behaves differently with or without user-defined copy constructor under GCC 8.0.1 : #include <cassert> struct S { int i; int *p; S() : i(0), p(&i) {} // S(const S &s) : i(s.i), p(&i) {} // #1 // S(const S &s) : i(s.i), p(s.p) {} // #2 // S(const S &s) = delete; // #3 }; S make_S() {return S{};} int main() { S s = make_S(); assert(s.p == &s.i); } With either of the commented user-defined copy constructors (even with #2, the one performing a simple shallow copy), the assertion will not fail, which means guaranteed copy elision works as expected. However, without any user

Exact moment of “return” in a C++-function

若如初见. 提交于 2019-12-02 19:48:31
It seems like a silly question, but is the exact moment at which return xxx; is "executed" in a function unambiguously defined? Please see the following example to see what I mean ( here live ): #include <iostream> #include <string> #include <utility> //changes the value of the underlying buffer //when destructed class Writer{ public: std::string &s; Writer(std::string &s_):s(s_){} ~Writer(){ s+="B"; } }; std::string make_string_ok(){ std::string res("A"); Writer w(res); return res; } int main() { std::cout<<make_string_ok()<<std::endl; } What I naively expect to happen, while make_string_ok

Copy elision for pass-by-value arguments

…衆ロ難τιáo~ 提交于 2019-12-01 02:26:15
Given struct Range{ Range(double from, double to) : from(from), to(to) {} double from; double to; }; struct Box{ Box(Range x, Range y) : x(x), y(y) {} Range x; Range y; }; suppose we run Box box(Range(0.0,1.0),Range(0.0,2.0)) . Could a modern compiler with optimizations enabled avoid copying Range objects altogether during this construction? (i.e. construct the Range objects inside box to begin with?) interjay There are actually two copies being performed on each Range object passed to the constructor. The first happens when copying the temporary Range object into the function parameter. This

Can copy elision occur in catch statements?

老子叫甜甜 提交于 2019-11-30 19:22:36
Consider an exception class with a copy constructor with side-effects. Can a compiler skip calling the copy constructor here: try { throw ugly_exception(); } catch(ugly_exception) // ignoring the exception, so I'm not naming it { } What about this: try { something_that_throws_ugly_exception(); } catch(ugly_exception) // ignoring the exception, so I'm not naming it { } (yes, I know this is all very ugly, this was inspired by another question ) Yes, it can be elided both during throwing and catching. For catching it can be elided only when the type specified in the catch clause is the same (save