¿Puede `* this` ser` move () `d?

Me gustaría definir una clase para ordenar datos; cuando finalice la clasificación, me gustaríamove los datos ordenados desde su interior, lo que probablemente invalidará el objeto de cálculo.

Creo que esto es posible con elstatic funciónextractData abajo:

class Marshaller
{
  public:
    static DataType extractData(Marshaller&& marshaller)
    {
      return std::move(marshaller.data);
    }
  private:
    DataType data;
}

Sin embargo, es un poco incómodo llamar:

Marshaller marshaller;
// ... do some marshalling...
DataType marshalled_data{Marshaller::extractData(std::move(marshaller))};

Entonces, ¿puedo envolverlo con una función miembro?

DataType Marshaller::toDataType()
{
  return Marshaller::extractData(std::move(*this));
}

Esto, por supuesto, se llamaría usando:

DataType marshalled_data{marshaller.toDataType()};

... que, para mí, se ve mucho mejor. Pero esostd::move(*this) La cosa parece terriblemente sospechosa. En el contexto de la llamada atoDataType(), marshaller no se puede volver a usar, pero no creo que el compilador pueda saber eso: el cuerpo de la función podría estar fuera de la unidad de compilación de la persona que llama, por lo que no hay nada que indique quemarshaller ha tenidomove() aplicado a ella.

¿Es este comportamiento indefinido? ¿Está perfectamente bien? O en algún punto intermedio? ¿Hay una mejor manera de lograr el mismo objetivo, preferiblemente sin usar una macro o requerir que la persona que llama explícitamentemove marshaller?

EDITAR: Con G ++ y Clang ++, descubrí que no solo podía compilar el caso de uso anterior, sino que realmente podíacontinuar haciendo modificaciones a los datos subyacentes a través del agente de clasificación, luego vuelva a extraer los datos modificados utilizando eltoDataType función. También encontré que elya extraído datos enmarshalled_data continuó siendo cambiado pormarshaller, lo que indica que elmarshalled_data se comparte entre losmarshaller y el contexto de llamada, por lo que sospecho que hay una pérdida de memoria o un comportamiento indefinido (de doble eliminación) aquí.

EDITAR 2: Si pongo una declaración impresa enDataType'destructor, parecedos veces cuando la persona que llama deja el alcance. Si incluyo un miembro de datos enDataType que tiene una matriz, con un correspondientenew[] ydelete[], Yo tengo unglibc error "doble libre o corrupción". Así que no estoy seguro de cómo estopodría esté seguro, a pesar de que varias respuestas han dicho que está técnicamente permitido. Una respuesta completa debe explicar qué se requiere para usar esta técnica correctamente con un método no trivialDataType clase.

EDITAR 3: Esto es suficiente de una madriguera de conejo / lata de gusanos que he abiertootra pregunta para abordar mis preocupaciones restantes.

Respuestas a la pregunta(2)

Su respuesta a la pregunta