简体   繁体   English

在视觉 2019 中复制 Elision

[英]Copy Elision in visual 2019

I was trying to test a small code to check if my compiler (under Visual Studio 2019) does copy elision, as it is no more optional for some cases under C++17.我试图测试一个小代码来检查我的编译器(在 Visual Studio 2019 下)是否确实复制省略,因为在 C++17 下的某些情况下它不再是可选的。

So I tried the code below :所以我尝试了下面的代码:

#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;
}

So as far as I read, calling the function get() will trigger the RVO so I will get only ctor calls.因此,据我所知,调用函数 get() 将触发 RVO,因此我只会得到 ctor 调用。 But when I run the program I get (I added <<<< in front of lines that are related to copy after calling get() function):但是当我运行程序时,我得到(我在调用 get() 函数后在与复制相关的行前添加了 <<<< ):

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

When tried with gcc I get :尝试使用 gcc 时,我得到:

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

So seems that Microsoft still didn't implement the Copy elision, or is there wrong in my code so I missed the real charm of Copy elision?所以似乎微软仍然没有实现复制省略,或者我的代码有问题所以我错过了复制省略的真正魅力?

Thank you in advance先感谢您

None of the copies in this case are required to be elided by any (currently existing) version of C++.在这种情况下,任何(当前存在的)C++ 版本都不需要删除任何副本。 The standard lays down several copies: the copy from s to the return value object of get , and the copy from the reference parameter to push_back into the vector 's internal object.标准规定了几个副本:从sget的返回值对象的副本,以及从引用参数到push_backvector内部对象的副本。 The latter copy cannot be elided, and the former copy's elision is not guaranteed to happen at all.后一个副本不能被删除,前一个副本的删除根本不能保证发生。

If you're talking about C++17's guaranteed elision, this only applies to the use of a prvalue to initialize an object (of that type).如果您在谈论 C++17 的保证省略,这仅适用于使用纯右值来初始化对象(该类型)。 That never happens here (outside of the temporary parameter passed to call push_back , but that's normal for any version of C++), so it doesn't apply.这在这里永远不会发生(在传递给调用push_back的临时参数之外,但这对于任何版本的 C++ 都是正常的),所以它不适用。

Here's a simple test: if the source object of the hypothetical copy has a variable name, then elision if applicable is not mandatory.这是一个简单的测试:如果假设副本的源对象有一个变量名,则省略(如果适用)不是强制性的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM