Estoy creando una clase de tipo encadenamiento, como el pequeño ejemplo a continuación. Parece que al encadenar funciones miembro, se invoca el constructor de copia. ¿Hay alguna forma de deshacerse de la llamada al constructor de la copia? En mi ejemplo de juguete a continuación, es obvio que solo estoy tratando con temporales y, por lo tanto, "debería" (tal vez no según los estándares, pero lógicamente) ser una elisión. La segunda mejor opción, para copiar elisión, sería llamar al constructor del movimiento, pero este no es el caso.
class test_class {
private:
int i = 5;
public:
test_class(int i) : i(i) {}
test_class(const test_class& t) {
i = t.i;
std::cout << "Copy constructor"<< std::endl;
}
test_class(test_class&& t) {
i = t.i;
std::cout << "Move constructor"<< std::endl;
}
auto& increment(){
i++;
return *this;
}
};
int main()
{
//test_class a{7};
//does not call copy constructor
auto b = test_class{7};
//calls copy constructor
auto b2 = test_class{7}.increment();
return 0;
}
Editar: algunas aclaraciones. 1. Esto no depende del nivel de optimización. 2. En mi código real, tengo objetos más complejos (p. Ej., Montón asignado) que ints
auto b = test_class{7};
no llama al constructor de copias porque es realmente equivalente test_class b{7};
y los compiladores son lo suficientemente inteligentes como para reconocer este caso y, por lo tanto, pueden eludir fácilmente cualquier copia. No se puede hacer lo mismo b2
.
std::cout
) en su copiadora? Sin ella, la copia debería optimizarse.