gpt4 book ai didi

C++11 昂贵的右值临时

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:42:02 26 4
gpt4 key购买 nike

我有一些要插入和操纵的轻型物体,然后我想将它们包含在一个更复杂的物体中。有一个应保持不变的查找表。这个想法看起来很简单,但是这样做的一行 - b += c(a); - 创建了一个昂贵的临时文件。

#include <vector>
static int count;

struct costly {
/* std::map<std::string, int> and whatnot */
int b;

~costly() { count++; }
costly(int b): b(b) { }
costly &operator+= (costly &rhs) { b += rhs.b; return *this; }
};

/* Note the assumption above constructor exists for rhs */
costly operator* (const costly &lhs, costly rhs) {
rhs.b *= lhs.b; return rhs;
}

struct cheap {
/* Consider these private or generally unaccessible to 'costly' */
int index, mul;

cheap(int index, int mul): index(index), mul(mul) { }
costly operator() (const std::vector<costly> &rhs) {
/* Can we do without this? */
costly tmp = rhs[index] * mul; return tmp;
}
};

int main(int argc, char* argv[]) {
std::vector<costly> a = {1, 2}; costly b(1); cheap c = {1, 2};
/* Above init also calls the destructor, don't care for now */
count = 0;
b += c(a);
return count;
}

我一直在阅读 RVO 和 C++11 的右值,但我还不能完全理解它们以完全消除引入的中间值。上面只创建了一个,因为 rhs 的构造函数可用。最初我有这个;

costly operator* (costly lhs, int rhs) {
lhs.b *= rhs; return lhs;
}

/* ... */

costly operator() (const std::vector<costly> &rhs) {
return rhs[index] * mul;
}

但是,这与我的直觉相反,导致 count 甚至为 2。为什么编译器没有理解我的意图?

最佳答案

RVO 不适用于函数参数,因此您的 * 运算符正在禁止它。为了启用 RVO,您需要参数的本地拷贝。然后,您可以通过提供采用右值引用的重载来进行优化(前提是 coSTLy 具有高效的移动复制构造函数)。例如,

costly operator*(const costly& c, int i)
{
costly ret = c;
ret += 1;
return ret;
}

costly operator*(costly&& c, int i)
{
costly ret = std::move(c);
ret += 1;
return ret;
}

关于C++11 昂贵的右值临时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26956820/

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