【发布时间】:2011-08-17 11:28:13
【问题描述】:
我已经就这个问题提出了一些涉及到的问题,但我得到了不同的回答,所以我认为最好直接问。
假设我们有以下代码:
// Silly examples of A and B, don't take so seriously,
// just keep in mind they're big and not dynamically allocated.
struct A { int x[1000]; A() { for (int i = 0; i != 1000; ++i) { x[i] = i * 2; } };
struct B { int y[1000]; B() { for (int i = 0; i != 1000; ++i) { y[i] = i * 3; } };
struct C
{
A a;
B b;
};
A create_a() { return A(); }
B create_b() { return B(); }
C create_c(A&& a, B&& b)
{
C c;
c.a = std::move(a);
c.b = std::move(b);
return C;
};
int main()
{
C x = create_c(create_a(), create_b());
}
现在理想情况下,create_c(A&&, B&&) 应该是空操作。与创建 A 和 B 并在堆栈上传递对它们的引用的调用约定不同,应该创建 A 和 B 并按值传递,而不是返回值 c。使用 NRVO,这意味着直接创建它们并将它们传递给 x,而函数 create_c 不需要做进一步的工作。
这样可以避免创建 A 和 B 的副本。
有没有办法允许/鼓励/强制编译器的这种行为,或者优化编译器通常会这样做吗?这仅在编译器内联函数时才有效,还是跨编译单元有效。
(我认为这可以跨编译单元工作...)
如果create_a() 和create_b() 带了一个隐藏参数来放置返回值,他们可以直接将结果放入x,然后通过引用传递给create_c(),不需要做任何事情并且立即返回。
【问题讨论】:
标签: c++ optimization c++11