Pregunta

Creo que me meteré en ello y comenzaré con el código:

#include <iostream>
#include <fstream>
#include <string>

class test : public std::ofstream
{
    public:
        test(const std::string& filename) { this->open(gen_filename(filename)); };
        test(const test&) = delete;
        //test(test&& old) = default; // Didn't compile
        test(test&& old) {};
    private:
        std::string gen_filename(const std::string& filename) 
        { return filename + ".tmp"; }
};

int main()
{
    auto os = test("testfile");
    os << "Test1\n";
    os << "Test2\n";
}

Básicamente, necesito devolver un de Stream. Por supuesto, no puede copiar un OFStream, así que jugueteé con el código en la prueba de clase, y obtuve lo anterior para compilar y trabajar como era de esperar (en GCC 4.5).

Pero tengo un mal presentimiento, esto se debe a que mi compilador hace "optimización del valor de retorno" (RTO) en "Auto OS = test ()". De hecho, si se modifica a lo siguiente:

int main()
{
    auto os = test("testfile");
    os << "Test1\n";
    auto os2 = std::move(os);
    os2 << "Test2\n";
}

Ya no obtengo Test1 y Test2 en la salida.

La cuestión es que la clase "prueba" de la clase no es copiable, por lo que no hay posibilidad de que se duplique el Ofstream. Solo quiero poder devolverlo de una función. Y parece que puedo hacer eso con GCC.

Prefiero no tener consejos inteligentes de Rereference a un montón asignado de Stream, o reabrir el archivo, ya que actualmente funciona sin hacer esas cosas. Solo tengo la sensación de que estoy siendo un poco "no estándar" en mi enfoque, por lo que una forma estándar de hacer lo que he descrito sería genial.

¿Fue útil?

Solución

Voy a responder a mi propia pregunta aquí:

En el GCC C ++ 0x Características de la biblioteca Página, eche un vistazo al artículo 27.9, que dice:

27.9 - Siguientes basadas en archivos - Operaciones parciales - Falta de movimiento y intercambio

Supongo que ese es probablemente el problema que tengo con GCC.

Otros consejos

El problema es con esto:

test(test&& old) {};

Esto te permite construir un nuevo test de un rValue test, sí, pero no dice nada sobre su base, que simplemente se está construyendo por defecto (sin archivo abierto). Lo que quieres es esto:

test(test&& old) : std::ofstream(std::move(old)) {};

Que moverá la transmisión de old en la base.

¿La persona que llama necesita saber que está devolviendo un ofstream, o tendría más sentido devolver un streambuf, ¿Y deja que la persona que llame la envuelva dentro de una transmisión?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top