سؤال

Why calling get_data2() results in additional c-tor call (g++ 4.7.1 -std=c++11 -O3)?

Code:

#include <iostream>

struct data {
    data(data&&){std::cout << "cted(&&): " << (void*) this << std::endl; }
    data(data const&){std::cout << "cted(c&): " << (void*) this << std::endl; }
    data(){std::cout << "cted(): " << (void*) this << std::endl; }
    ~data(){std::cout << "dted(): " << (void*) this << std::endl; }
};

data create_data() { return data(); }

// with this one the c-tor is called twice
data get_data2() { return std::move(create_data()); }

// with this one the c-tor is called once
data get_data1() { return create_data(); }
int main() { data var = get_data1(); return 0; }

Output with get_data2():

cted(): 0x7ffffb2cd3df
cted(&&): 0x7ffffb2cd40f
dted(): 0x7ffffb2cd3df
dted(): 0x7ffffb2cd40f

Output with get_data1():

cted(): 0x7ffffd7f230f
dted(): 0x7ffffd7f230f
هل كانت مفيدة؟

المحلول

The problem is that the explicit std::move prohibits copy elision, see Why does std::move prevent RVO? Another problem is that the explicit move is also unnecessary because in data create_data() { return data(); } you are already returning an rvalue.

As a side note: A very similar question came up a while ago and it turned out that the way you are using to track object creation is very unreliable, partly because the object is empty, see RVO force compilation error on failure.

Long story short: use only the data create_data() { return data(); } version.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top