Скопируйте Elision в Visual 2019 - PullRequest
0 голосов
/ 18 февраля 2020

Я пытался протестировать небольшой код, чтобы проверить, выполняет ли мой компилятор (в Visual Studio 2019) копирование elision, поскольку в некоторых случаях это не является обязательным для C ++ 17.

Поэтому я попытался код ниже:

#include <iostream>
#include <vector>
using namespace std;

struct myStruct
{
    myStruct() { cout << "default ctor" << endl; }
    myStruct(const myStruct& str) { cout << "copy ctor" << endl; }
    myStruct& operator=(myStruct other) { cout << "Copy assignement" << endl; return *this; }
    myStruct(myStruct&& str) noexcept { cout << "move ctor" << endl; }
    myStruct& operator=(myStruct&& other) { cout << "move assignement" << endl; return *this; }
    ~myStruct() { cout << "deleted" << endl; }
};

myStruct get()
{
    myStruct s;
    return s;
}

int main()
{
    vector<myStruct> vect;
    vect.reserve(10);
    cout << "Creating The Vector" << endl;
    vect.push_back(get());
    vect.push_back(get());
    cout << "Cretion End" << endl;
    return 0;
}

Итак, насколько я прочитал, вызов функции get () вызовет RVO, поэтому я получу только вызовы ctor. Но когда я запускаю программу, я получаю (я добавил <<<< перед строками, которые связаны с копированием после вызова функции get ()): </p>

Creating The Vector
default ctor
move ctor
deleted
move ctor  <<<<
deleted    <<<<
default ctor
move ctor
deleted
move ctor  <<<<
deleted    <<<<
Cretion End
deleted
deleted

При попытке с помощью g cc я получаю :

Creating The Vector
default ctor
move ctor
deleted
default ctor
move ctor
deleted
Cretion End
deleted
deleted

Похоже, что Microsoft до сих пор не реализовала Elision Copy, или в моем коде есть ошибка, поэтому я упустил реальную прелесть Copy elision?

Заранее спасибо

1 Ответ

1 голос
/ 18 февраля 2020

Ни одна из копий в этом случае не должна быть опущена какой-либо (в настоящее время существующей) версией C ++. Стандарт устанавливает несколько копий: копию из s в объект возвращаемого значения get и копию из ссылочного параметра в push_back во внутренний объект vector. Последняя копия не может быть удалена, и исключение первой копии не гарантируется вообще.

Если вы говорите о гарантированном исключении C ++ 17, это относится только к использованию prvalue для инициализации объект (такого типа). Это никогда не происходит здесь (за исключением временного параметра, переданного в вызов push_back, но это нормально для любой версии C ++), поэтому он не применяется.

Вот простой тест: если исходный объект гипотетическая копия имеет имя переменной, тогда исключение не обязательно, если применимо.

...