¿Existe alguna forma de llamar al destructor de un elemento reemplazado al utilizar std::replace?
Tengo un vector de objetos en el que quiero reemplazar un elemento por otro. Usar std::replace parecía apropiado, así que lo intenté.
Sin embargo, estaba preocupado por el paradero del elemento reemplazado, así que hice algunas pruebas:
class A {
public:
A(const int ii): i(ii) {std::cout << “Constructor ” << i << std::endl;}
~A(){std::cout << “Destructor ” << i << std::endl;}
auto operator ==(const A& a){return i == a.i;}
int i;
};
int main() {
std::vector v;
v.reserve(4);
v.emplace_back(10);
v.emplace_back(20);
v.emplace_back(40);
v.emplace_back(30);
for(const auto& elt : v) {
std::cout << elt.i << ‘ ‘;
}
std::cout << std::endl;
std::replace(v.begin(), v.end(), v[2], A(25));
for(const auto& elt : v) {
std::cout << elt.i << ' ';
}
std::cout << "End of program" << std::endl;
}
El tercer elemento del vector es reemplazado, pero como puede ver, el destructor del objeto reemplazado no se llama:
Constructor 10
Constructor 20
Constructor 40
Constructor 30
10 20 40 30
Constructor 25
10 20 25 30 End of program
Destructor 10
Destructor 20
Destructor 25
Destructor 30
Como el comportamiento es el mismo en cada compilador, supongo que está destinado, pero ¿hay alguna forma de que se llame al destructor en ese caso?
Ejemplo de prueba: https://godbolt.org/z/YTaKcrTEn
¡Gracias!
davy.ai
La razón por la cual el destructor del objeto remplazado no se llama es porque
std::replace
remplaza los elementos en su lugar, sin realmente eliminar o destruir los viejos elementos. Los viejos elementos aun existen dentro del vector, pero ahora son iguales al nuevo elemento que proporcionó.Si desea eliminar y destruir el viejo elemento al reemplazarlo, puede usar
std::replace_if
con una función lambda que regrese verdadero para el elemento que desea reemplazar y falso para el resto. Dentro de la lambda, también puede destruir el viejo elemento antes de reemplazarlo con el nuevo elemento.Aquí hay un ejemplo:
“`c++
std::replace_if(v.begin(), v.end(), [](const A& a){ return a.i == 40; },
{ return A(25); });
Esto encontrará el primer elemento en el vector con un valor de 40, lo reemplazará con una nueva instancia de
A
con un valor de 25 y luego lo eliminará del vector. Tenga en cuenta que eliminar un elemento de un vector puede ser costoso, especialmente si el vector es grande o contiene objetos complejos, así que use este método con precaución.