2016-08-24 10 views
1

Я был смущен, почему моя программа вела себя непредвиденным образом. Затем я написал эту упрощенную версию и обнаружил, что есть вызов конструктора «отсутствует».Отсутствует вызов конструктора

template <class T> 
class A 
{ 
public: 

    A() {std::cout << "default" << "\n";} // default ctor 

    A (const A& src)      // copy ctor 
    { 
     std::cout << "copy" << "\n"; 
    } 

    friend A<T> operator<<(A& a, unsigned i) 
    { 
     std::cout << "x1" << "\n"; 
     A tmp; 
     std::cout << "x2" << "\n"; 
     return tmp; 
    } 
}; 


int main() 
{ 
    A<int> a1; 
    A<int> a2(a1 << 2); 
} 

Выход

default 
x1 
default 
x2 

То, что я ожидал был

default 
x1 
default 
x2 
copy 

как г-значение, возвращенное a1 << 2 будет принят в параметр копии CTOR const A&. Но это не то, что происходит. А если нет, что тогда, по крайней мере, я бы ожидать

default 
x1 
default 
x2 
default 

, потому что я бы подумал, что конструктор a2 нужно будет называться.

Что здесь происходит?

+1

Скопировать elision. Я думаю, что компиляция без оптимизации должна это сделать. – Rakete1111

+1

Я читал об этом, но для меня это еще не объясняло, почему даже вариант с 3 вызовами по умолчанию - это случай. –

+0

И я вообще не компилирую с оптимизацией. –

ответ

2

Это из-за копия elision. Более конкретно, N AMED R eturn В ALUE О ptimization или NRVO.

NRVO происходит, когда локальная (к функции) переменной с автоматической продолжительности хранения возвращается значение из функции, и это значение присваивается переменной:

friend A<T> operator<<(A& a, unsigned i) 
{ 
    //... 
    A tmp; //automatic storage variable 
    //... 
    return tmp; //returned by value 
} 

A<int> a2(a1 << 2); //Assigned to a2 

Компилятор разрешено игнорировать копия tmp - a2. Это в основном означает, что когда функция заканчивается, память tmp не освобождается! Затем он просто назначает a2 этой ячейке памяти, что в основном приводит к «копированию» tmp.

Это происходит, если даже конструкторы и деструктор копирования/перемещения имеют побочные эффекты, такие как выдача некоторого значения. Однако следует отметить, что это реализация определена, некоторые компиляторы могут также вывести второй и/или третий случай.

Для других форм копирования, см. those answers.