ここに示されているように、NRVO は行r
によって暗示されたのコピーを省略します。return r;
#include <iostream>
struct A {
const char* name;
A( const char* name_ ):name(name_) { std::cout << "created " << name << "\n"; }
A(A const&){ std::cout << "copied " << name << "\n"; }
A(A &&){ std::cout << "moved " << name << "\n"; }
};
A f() {
std::cout << "start of f()\n";
A const r("bob");
std::cout << "body of f()\n";
return r;
}
int main() {
A x = f();
}
また、コピーインmain
も省略されます。
NRVO と RVO を他の方法でブロックすると (たとえば-fno-elide-constructors
、GCC でコンパイルするときにフラグを使用するなど)、オブジェクトがdconst
の代わりにコピーされる可能性があります。からコピー コンストラクターを削除すると、move
これを確認できます。A
#include <iostream>
struct A {
const char* name;
A( const char* name_ ):name(name_) { std::cout << "created " << name << "\n"; }
//A(A const&){ std::cout << "copied " << name << "\n"; }
A(A &&){ std::cout << "moved " << name << "\n"; }
};
A f() {
std::cout << "start of f()\n";
A const r("bob");
std::cout << "body of f()\n";
return r;
}
int main() {
A x = f();
}
コードはコンパイルされなくなります。NRVO が発生する限り、コピー コンストラクターは実行されませんが、その存在はconst
ローカル変数によって必要とされます。
現在、NRVO には、問題の関数のすべての実行パスに沿って返される単一の変数など、いくつかのことが必要です。「中止」して を実行するreturn A()
と、NRVO がブロックされ、const
ローカル変数が突然コピーを強制しますすべての返品サイト。