我想验证以下优化是否按预期工作:
所以我写了这个小程序:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我在启用优化的情况下编译了它:
$ g++ -o test -O3 main.cpp ; ./test
Run Code Online (Sandbox Code Playgroud)
这是输出:
Test RVO:
Test named RVO:
Test PassByValue:
*** COPY ***
Test assignment:
*** COPY ***
*** ASSIGNMENT ***
Run Code Online (Sandbox Code Playgroud)
根据输出RVO并命名为RVO按预期工作.但是,不会为赋值运算符和调用时执行复制省略PassByValue.
用户定义的复制构造函数不允许复制省略吗?(我知道标准明确允许使用RVO,但是当通过值传递时我不知道复制省略.)有没有办法在不定义复制构造函数的情况下验证复制省略?
Bjö*_*lex 10
标准说(第12.8.15段):
在以下情况下允许复制操作的这种省略(可以组合以消除多个副本):
在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-nonqualified类型的非易失性自动对象的名称时,可以通过构造自动对象来省略复制操作直接进入函数的返回值
当一个尚未绑定到引用(12.2)的临时类对象被复制到具有相同cv-unqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制操作.省略副本
这些情况都不适用于此,因此不允许使用省略号.第一个是显而易见的(没有回报).第二个是不允许的,因为您传入的对象不是临时的.
请注意,您的代码仍然正常,因为您无论如何都必须创建副本.要废除该副本,您必须使用C++ 0x的移动语义.
您使用复制构造函数的方式无法省略,因为复制的对象在调用后仍然存在.
如果你这样尝试,它可能会更好:
PassByValue(Foo(512, 'a'));
Run Code Online (Sandbox Code Playgroud)
所有优化都是允许的,但不是必需的,因此由每个编译器决定它能做什么和将做什么.
| 归档时间: |
|
| 查看次数: |
1121 次 |
| 最近记录: |