gpt4 book ai didi

c++ - 是否有一个不会被省略的 move 构造的简单示例?

转载 作者:可可西里 更新时间:2023-11-01 18:29:37 24 4
gpt4 key购买 nike

我正在尝试很好地学习 move 语义,以便将它介绍给我的学生。我一直在使用高度简化的类似 vector 或类似字符串的类来管理内存,并且其成员输出消息以演示它们的事件。我正在尝试开发一组简单的示例来向学生展示。

在 gcc 4.7 和 clang 中,RVO 和其他地方的构造省略积极地消除了复制和 move 构造,所以虽然我可以很容易地看到 move 分配在工作,但我唯一一次看到 move 构造在工作是如果我关闭构造省略在带有 -fno-elide-constructors 的 gcc 4.7 中。

显式复制构造语句

MyString newString(oldString);

即使启用了省略,也会调用复制构造函数。但是像

MyString newString(oldString1 + oldString2); 

因为省略而没有调用 move 构造函数。

任何明确使用 std::move 的东西都不会成为一个简单的例子,因为解释 std::move 必须稍后再做。

所以我的问题是:是否有一个简单的代码示例可以调用 move 构造,即使复制/move 构造函数被省略?

最佳答案

这个简单的例子是返回函数的参数。该标准明确禁止在这种情况下省略 move (并不是说他们可以...):

std::vector<int> multiply( std::vector<int> input, int value ) {
for (auto& i : input )
i *= value;
return input;
}

此外,您可以明确请求 move 构造以获得更简单但更人工的示例:

T a;
T b( std::move(a) );

嗯...还有一个不涉及std::move(技术上可以省略,但大多数编译器可能不会):

std::vector<int> create( bool large ) {
std::vector<int> v1 = f();
std::vector<int> v2 = v1; // modify both v1 and v2 somehow
v2.resize( v2.size()/2 );
if ( large ) {
return v1;
} else {
return v2;
}
}

虽然优化器可以通过重写代码来忽略它:

std::vector<int> create( bool large ) {
if ( large ) {
std::vector<int> v1 = f();
std::vector<int> v2 = v1; // modify both v1 and v2 somehow
v2.resize( v2.size()/2 );
return v1;
} else {
std::vector<int> v1 = f();
std::vector<int> v2 = v1; // modify both v1 and v2 somehow
v2.resize( v2.size()/2 );
return v2;
}
}

我非常怀疑编译器是否真的会这样做。请注意,在创建 v1v2 之前,在每个代码路径中返回的对象都是已知的,因此优化器可以在重写后在返回位置找到正确的对象。

12.8/31 中描述了可以省略复制/move 的情况。如果您设法编写不属于这些类别的代码并且该类型具有 move 构造函数,则将调用 move 构造函数。

关于c++ - 是否有一个不会被省略的 move 构造的简单示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12285811/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com