У меня есть следующий код для проверки RVO с флагом компиляции -std=c++17
и -std=c++2@
с использованием C++2@(GNU)
компилятора
struct C
{
C() = default;
C(const C& obj){PrintAddress("copy ctor"); }
void PrintAddress( std::string mark = "") const { std::cout << "> " << mark << "\t" << this << '\n'; }
};
C get() { C c; c.PrintAddress("get()"); return c; }
int main()
{
C rvo = get();
rvo.PrintAddress("rvo's");
}
Вывод:
> get() 0x7ffe7467db7c
> rvo's 0x7ffe7467db7c
Однако, если используется конструктор копирования по умолчанию:
struct C
{
C() = default;
C(const C& obj) = default;
void PrintAddress( std::string mark = "") const { std::cout << "> " << mark << "\t" << this << '\n'; }
};
Вывод становится:
> get() 0x7ffff37e7b4c
> rvo's 0x7ffff37e7bac //emmmm
Исключение копирования отключено.
на основе ссылка , копия elision требуется, когда:
При следующих обстоятельствах компиляторам разрешено, но не требуется опускать копирование и перемещать (начиная с C ++ 11) конструкцию объектов класса, даже есликонструктор копирования / перемещения (начиная с C ++ 11) и деструктор имеют видимые побочные эффекты.Объекты создаются непосредственно в хранилище, где они в противном случае были бы скопированы / перемещены.Это оптимизация: даже когда это происходит и конструктор копирования / перемещения (начиная с C ++ 11) не вызывается, он все равно должен присутствовать и быть доступным (как если бы оптимизация вообще не происходила) ,в противном случае программа некорректно сформированаМой вопрос, почему это?Конструктор копирования даже не будет вызываться в разрешении копирования.Почему это должно быть представлено?