【发布时间】:2011-06-17 17:55:15
【问题描述】:
我想验证以下优化是否按预期工作:
- RVO
- 命名为 RVO
- 按值传递参数时复制省略
所以我写了这个小程序:
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <vector>
struct Foo {
Foo(std::size_t length, char value) : data(length, value) { }
Foo(const Foo & rhs) : data(rhs.data) { std::cout << "*** COPY ***" << std::endl; }
Foo & operator= (Foo rhs) {
std::cout << "*** ASSIGNMENT ***" << std::endl;
std::swap(data, rhs.data); // probably expensive, ignore this please
return *this;
}
~Foo() { }
std::vector<char> data;
};
Foo TestRVO() { return Foo(512, 'r'); }
Foo TestNamedRVO() { Foo result(512, 'n'); return result; }
void PassByValue(Foo inFoo) {}
int main()
{
std::cout << "\nTest RVO: " << std::endl;
Foo rvo = TestRVO();
std::cout << "\nTest named RVO: " << std::endl;
Foo named_rvo = TestNamedRVO();
std::cout << "\nTest PassByValue: " << std::endl;
Foo foo(512, 'a');
PassByValue(foo);
std::cout << "\nTest assignment: " << std::endl;
Foo f(512, 'f');
Foo g(512, 'g');
f = g;
}
我在启用优化的情况下编译它:
$ g++ -o test -O3 main.cpp ; ./test
这是输出:
Test RVO:
Test named RVO:
Test PassByValue:
*** COPY ***
Test assignment:
*** COPY ***
*** ASSIGNMENT ***
根据输出 RVO 和命名的 RVO 按预期工作。但是,赋值运算符和调用PassByValue时不执行复制省略。
用户定义的复制构造函数是否允许复制省略? (我知道标准明确允许 RVO,但我不知道按值传递时的复制省略。)有没有一种方法可以在不定义复制构造函数的情况下验证复制省略?
【问题讨论】:
-
为了清楚起见,(N)RVO 是复制省略。它们不是唯一的形式,但是说您的示例表明未执行复制省略是不准确的。
-
Cooy elision 通常允许用于所有临时对象,但不适用于命名或绑定到引用的对象。似乎 gcc 执行的正是允许的。
-
@Dennis Zickefoose 谢谢,我修正了文本。
标签: c++