Return Value Optimization (RVO)¶
Before starting¶
// foo.h
#include <iostream>
struct Foo {
Foo() {
std::cout << "Constructor" << "\n";
}
~Foo() {
std::cout << "Destructor" << "\n";
}
Foo(const Foo&) {
std::cout << "Copy Constructor" << "\n";
}
Foo(Foo &&) {
std::cout << "Move Constructor" << "\n";
}
Foo& operator=(const Foo&) {
std::cout << "Copy Assignment" << "\n";
return *this;
}
Foo& operator=(Foo &&){
std::cout << "Move Assignment" << "\n";
return *this;
}
};
Return Value Optimization¶
#include "foo.h"
Foo FooRVO() {
return Foo();
}
int main(int argc, char *argv[]) {
Foo f = FooRVO();
}
Named Return Value Optimization¶
#include "foo.h"
Foo FooNRVO() {
Foo foo;
return foo;
}
int main(int argc, char *argv[]) {
Foo f = FooNRVO();
}
Copy Elision¶
#include "foo.h"
void CopyElision(Foo foo) {}
int main(int argc, char *argv[]) {
CopyElision(Foo());
}
Return a Global (w/o RVO)¶
#include "foo.h"
const Foo foo;
Foo ReturnGlobal() {
return foo;
}
int main(int argc, char *argv[]) {
Foo f = ReturnGlobal();
}
Return a Parameter (w/o RVO)¶
#include "foo.h"
Foo ReturnParam(Foo foo) {
return foo;
}
int main(int argc, char *argv[]) {
Foo f = ReturnParam(Foo());
}
Runtime Decision (w/ RVO)¶
#include "foo.h"
Foo FooRVO(bool is_x) {
return is_x ? Foo() : Foo();
}
int main(int argc, char *argv[]) {
Foo foo = FooRVO(true);
}
Runtime Decision (w/ RVO, w/o NRVO)¶
#include "foo.h"
Foo RVOButNoNRVO(bool is_x) {
Foo x;
return is_x ? x : Foo();
}
int main(int argc, char *argv[]) {
Foo f = RVOButNoNRVO(false);
}
Runtime Decision (w/o NRVO)¶
#include "foo.h"
Foo FooNoNRVO(bool is_x) {
Foo x, y;
return is_x ? x : y;
}
int main(int argc, char *argv[]) {
Foo foo = FooNoNRVO(true);
}
Return by std::move
(w/o RVO)¶
#include "foo.h"
#include <utility>
Foo FooMove() {
return std::move(Foo());
}
int main(int argc, char *argv[]) {
Foo foo = FooMove();
}
Return by std::move
(w/o NRVO)¶
#include "foo.h"
#include <utility>
Foo FooMove() {
Foo foo;
return std::move(foo);
}
int main(int argc, char *argv[]) {
Foo foo = FooMove();
}
Return a Member (w/o RVO)¶
#include "foo.h"
struct Bar {
Foo foo;
};
Foo ReturnMember() {
return Bar().foo;
}
int main(int argc, char *argv[]) {
Foo f = ReturnMember();
}