gpt4 book ai didi

c++ - 保证省略和链式函数调用

转载 作者:IT老高 更新时间:2023-10-28 22:02:07 25 4
gpt4 key购买 nike

假设我有以下类型:

struct X {
X& operator+=(X const&);
friend X operator+(X lhs, X const& rhs) {
lhs += rhs;
return lhs;
}
};

我有声明(假设所有命名的变量都是 X 类型的左值):

X sum = a + b + c + d;

在 C++17 中,我对这个表达式将执行多少个拷贝和移动有什么保证?非保证省略呢?

最佳答案

这将执行 1 次复制构造和 3 次移动构造。

  1. 复制 a 以绑定(bind)到 lhs
  2. 将构造lhs移出第一个+
  3. 第一个 + 的返回值会通过省略号绑定(bind)到第二个 + 的按值 lhs 参数。
  4. 第二个lhs的返回将引发第二个移动构造。
  5. 第三个lhs的返回会产生第三个移动构造。
  6. 第三个+返回的临时值会在sum处构造。

对于上面描述的每个移动结构,都有另一个移动结构可以选择省略。所以你只有保证有 1 个拷贝和 6 个 Action 。但实际上,除非你-fno-elide-constructors,否则你将有1个拷贝和3个 Action 。

如果你在这个表达式之后没有引用 a,你可以进一步优化:

X sum = std::move(a) + b + c + d;

产生 0 个拷贝和 4 个移动(使用 -fno-elide-constructors 进行 7 个移动)。

上面的结果已经被一个 X 证实了,它已经检测了复制和移动构造函数。


更新

如果您对优化它的不同方法感兴趣,您可以从重载 X const&X&& 上的 lhs 开始:

friend X operator+(X&& lhs, X const& rhs) {
lhs += rhs;
return std::move(lhs);
}
friend X operator+(X const& lhs, X const& rhs) {
auto temp = lhs;
temp += rhs;
return temp;
}

这将事情减少到 1 个拷贝和 2 个移动。如果您愿意限制您的客户通过引用捕获您的 + 的返回,那么您可以从这样的重载之一返回 X&&:

friend X&& operator+(X&& lhs, X const& rhs) {
lhs += rhs;
return std::move(lhs);
}
friend X operator+(X const& lhs, X const& rhs) {
auto temp = lhs;
temp += rhs;
return temp;
}

让您减少 1 个拷贝和 1 个移动。请注意,在此最新设计中,如果您的客户曾经这样做过:

X&& x = a + b + c;

那么 x 是一个悬空引用(这就是 std::string 不这样做的原因)。

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

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