У меня есть следующий код:Почему конструктор копирования не вызывается, когда объект передается функции
#include <iostream>
using namespace std;
class foo
{
public:
foo(int a, int b) :
a_(a), b_(b)
{ cout << "regular const" << endl; }
foo(const foo& f) :
a_(f.a_), b_(f.b_)
{ cout << "copy const" << endl; }
foo& operator=(const foo& rhs)
{cout << "copy= const" << endl; a_ = rhs.a_; b_ = rhs.b_; return *this; }
int a_, b_;
};
void bar(foo f)
{ }
int main()
{
foo f1(10, 20);
cout << "------" << endl;
bar(f1);
cout << "------" << endl;
bar(foo(11, 22)); // line 29
cout << "------" << endl;
bar({13, 23}); // line 32
cout << "------" << endl;
}
я получаю следующий результат:
$ ./a.out
regular const
------
copy const
------
regular const
------
regular const
------
Для линии 29 и линии 32, я ожидал временный объект, который должен быть создан в главном (вызов обычного конструктора), а затем вызывается конструктор копирования при передаче в bar(). Из вывода я вижу, что компилятор делает некоторую оптимизацию и угадывает, возможно, просто создает объект в стеке при вызове bar() и вызывается только обычный конструктор. Может кто-то, пожалуйста, помогите мне понять, какой тип оптимизации делается или что происходит под капотом.
Позволяет ли строка вызова() использовать строки 29 и 32 эквивалента до сгенерированного кода? Я понимаю, что строка 29 более читаема.
Я изменил бар() следующим образом:
void bar(const foo& f)
{ }
я получаю тот же результат для линий 29 и 32. В этом случае, когда объект создаваемой?
Спасибо, Ахмед.
копирования список инициализация и копирование элизия не строят временные на стороне вызова, то же самое с возвращением –
http://en.cppreference.com/w/cpp/language/copy_elision – Mat
@Mat благодарственного вы за упоминание «копия элиции», я раньше не сталкивался с этой терминологией. И для предоставления ссылки. –