Ho voluto verificare il se le seguenti ottimizzazioni funzionano come previsto:Condizioni per copia elisione?
- RVO
- Chiamato RVO
- Copia elisione quando passa un argomento per valore
Così ho scritto questo piccolo programma :
#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;
}
E l'ho compilato con ottimizzazioni it abili:
$ g++ -o test -O3 main.cpp ; ./test
Questo è uscita:
Test RVO:
Test named RVO:
Test PassByValue:
*** COPY ***
Test assignment:
*** COPY ***
*** ASSIGNMENT ***
Secondo l'uscita RVO e il lavoro RVO nominato come previsto. Tuttavia, la copia elision non viene eseguita per l'operatore di assegnazione e quando si chiama PassByValue
.
L'elisione della copia non è consentita sui costruttori di copia definiti dall'utente? (So che RVO è esplicitamente consentito dallo standard, ma non conosco copia elision quando si passa per valore.) Esiste un modo per verificare la copia elision senza definire i costruttori di copia?
Giusto per essere chiari, (N) RVO * è * copia elisione. Non sono le uniche forme, ma per dire che il tuo esempio mostra che la copia di elision non viene eseguita è imprecisa. –
L'elisione del cooy è generalmente consentita per tutti gli oggetti temporanei, ma non per oggetti con o senza riferimento. Sembra che gcc esegua esattamente i permessi. –
@Dennis Grazie Zickefoose, ho corretto il testo. – StackedCrooked