Estou criando uma classe do tipo encadeamento, como o pequeno exemplo abaixo. Parece que, ao encadear funções-membro, o construtor de cópia é chamado. Existe uma maneira de se livrar da chamada do construtor de cópia? No meu exemplo de brinquedo abaixo, é óbvio que estou lidando apenas com temporários e, portanto, "deveria" (talvez não pelos padrões, mas logicamente) haver uma elisão. A segunda melhor opção, copiar elision, seria chamar o construtor de movimento, mas esse não é o 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;
}
Edit: Alguns esclarecimentos. 1. Isso não depende do nível de otimização. 2. No meu código real, tenho objetos mais complexos (por exemplo, alocados por heap) do que ints
auto b = test_class{7};
não chama construtor de cópia porque é realmente equivalente test_class b{7};
e os compiladores são inteligentes o suficiente para reconhecer esse caso e, portanto, podem facilmente excluir qualquer cópia. O mesmo não pode ser feito b2
.
std::cout
) no seu copiador? Sem ele, a cópia deve ser otimizada.