Estoy intentando detectar, en el destructor, si estoy en una instancia temporal o no.
Lo primero que intenté fue cualificar los destructores:
~S( ) & { ... }
~S( ) && { ... }
Con lo que obtuve un bonito mensaje de error:
error: destructors may not be ref-qualified
A continuación, intenté esto:
#include <iostream>
#include <list>
using namespace std;
struct S {
S( ) { algo( ); }
S( const S& ) : S( ) { }
S( S && ) { algo( ); }
void realAlgo( bool tmp, bool dest ) const {
cout << ( tmp ? "Temporal " : "No temporal " );
cout << ( dest ? "destructor" : "constructor" ) << endl;
}
void algo( bool dest = false ) & {
realAlgo( false, dest );
}
void algo( bool dest = false ) && {
realAlgo( true, dest );
}
~S( ) { algo( true ); }
};
int main( void ) {
list< S > lista{ S( ), S( S( ) ) };
cout << "Size: " << lista.size( ) << endl;
return 0;
}
Para mi sorpresa, la salida obtenida es:
No temporal constructor
No temporal constructor
No temporal constructor
No temporal constructor
No temporal destructor
No temporal destructor
Size: 2
No temporal destructor
No temporal destructor
Es decir, no se llama a la función miembro algo( ) &&
.
Tras pensarlo un poco, es un comportamiento lógico, dado que la decisión de llamar a una u otra versión de la función se realiza en tiempo de compilación. Al no poder cualificar los destructores, estos siempre llamaran a la versión &
de la función.
Así pues, cambié de táctica. ¿ Porqué no usar un indicador, y establecerlo en el move constructor ?
#include <iostream>
#include <list>
using namespace std;
struct S {
bool temp;
S( ) : temp( false ) { cout << "Constructor\n"; }
S( const S& ) : S( ) { }
S( S &&o ) : S( ) { o.temp = true; }
~S( ) {
cout << "Destructor de " << ( temp ? "temporal" : "no temporal" ) << endl;
}
};
int main( void ) {
list< S > lista{ S( ), S( S( ) ) };
cout << "Size: " << lista.size( ) << endl;
return 0;
}
El resultado me volvió a sorprender:
Constructor
Constructor
Constructor
Constructor
Destructor de no temporal
Destructor de no temporal
Size: 2
Destructor de no temporal
Destructor de no temporal
Así pues, la pregunta es: