gpt4 book ai didi

c++ - 复制省略、std::move 和链式函数调用

转载 作者:行者123 更新时间:2023-11-28 01:30:43 26 4
gpt4 key购买 nike

我一直在研究当复制省略没有直接分配给左值并且可能被链接或使用时它的行为如何,但没有找到任何具体的答案。

对于初学者,我理解在下面的例子中发生了NRVO,返回值直接构造在目标变量中:

Type MakeType() {
Type type;
// ...
return type;
}

Type a = MakeType();

但是,假设我们有另一个函数,它接受一个类型作为参数:

Type MakeComplexType(/*some signature*/ param_type) {
Type complex_type = param_type
// ...
return complex_type;
}

我们这样调用它:

Type t = MakeComplexType(MakeType());
  1. 是否可以将复制省略一直链接到 t
  2. 如果不是,我们是否可以策略性地使用 std::move,也许在函数调用本身上,如 std::move(MakeType()),以避免不必要的复制?
  3. param_type 的签名应该是什么,才能使上述对 t 的分配最有效?

最佳答案

复制省略是编译器用来防止不需要的复制的技术。基本上,它会在函数外部预分配内存并将其传入以供使用。如果是临时的,它将在堆栈中。

将 std::move 添加到返回类型没有帮助。您已经按值返回,因此您已经有一个右值。使用 std::move 将其设为非右值应该是空操作。我不知道细节,但是,在某些情况下,添加它会损害性能。

专注于 2:将 std::move 添加到函数调用只会在非 const 引用返回时产生副作用。在这些情况下,您很可能写了一个错误,因为原始错误将被移走。

对于数字 3:我最喜欢使用 f(Arg &&a),因为这需要所有调用者传递右值。如果性能不太重要,例如:您没有在分析中找到它。值参数(一些调用者可以复制)甚至 const-reference 都可以(函数不能接触参数,所以应该复制)。

如注释所示,该函数的实现还应编写 auto result = std::move(a),因为您的参数不会受益于 NRVO。

最新版本的 Clang 有关于何时应该使用 std::move 以及何时删除它的非常好的警告。我建议启用它们。 GCC 可能有一些类似的警告,但我不是最新的。

简而言之:您的原始代码是最好的版本,如果它有关于此的警告,请相信您的编译器。

关于c++ - 复制省略、std::move 和链式函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51641769/

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