es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Puntero a objeto constante con emplace_back

No entiendo cuándo se pueden usar variables/objetos const en colecciones (particularmente con emplace). El siguiente código funciona con objetos const directamente, pero no cuando se usan punteros a objetos const.

“`c++
#include <list>

class MyData { };

int main() {
std::list<><int, mydata="">> collection1{};
std::list<><int, mydata*="">> collection2{};

<pre><code>const MyData someData{};
const MyData* someDataPtr = &someData;

collection1.emplace_back(1, someData);
//collection2.emplace_back(1, someDataPtr); //¡Error de plantilla desordenado!
</code></pre>

}
“`

Supongo que no hay muchas ventajas en usar emplace_back en lugar de push_back para punteros, pero estoy usando std::pair para ilustrar que la otra parte del par podría ser algo grande/costoso.

Específicamente, mi pregunta es ¿por qué emplace_back funciona con un objeto const, pero no con un puntero a un objeto const? ¿Hay una manera razonable de lograr lo último?

Para cualquier persona que se pregunte sobre el caso de uso, tengo una función miembro a la que se le pasan los componentes del par, realiza algún procesamiento (pero no debe cambiar ningún dato) y luego coloca el par en la colección. Algo como:

c++
void add_to_schedule(const int id, const MyData* myData) {
//algún procesamiento
this->collection.emplace_back(id, myData);
}
</int,></int,>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Uso de variables/objetos const en colecciones con emplace

    El código proporcionado funciona con objetos const directamente, pero genera un error de plantilla al usar punteros a objetos const. La cuestión es por qué emplace_back funciona con un objeto const pero no con un puntero a un objeto const, y si hay alguna manera de lograr lo segundo.

    Al usar emplace_back, la función reenvía sus argumentos al constructor del tipo miembro, creando el objeto in situ. La razón por la que emplace_back funciona con objetos const es que el constructor que se llama para el pair toma sus argumentos como referencias const, por lo que emplace_back puede reenviar un objeto const como argumento.

    Por otro lado, al usar punteros a objetos const, la función emplace_back necesita convertir el puntero a una referencia a un objeto no constante. Esto no está permitido porque las funciones emplace necesitan preservar la constancia del objeto original, y convertir un puntero en una referencia no constante violaría eso.

    Para lograr lo segundo, es posible usar const_cast para eliminar el calificador const del puntero. Sin embargo, esto no se recomienda porque es inseguro y viola la corrección constante del programa.

    void add_to_schedule(const int id, const MyData* myData) {
       //procesamiento
       this->collection.emplace_back(id, const_cast<mydata*>(myData));
    }
    

    En resumen, es seguro usar emplace_back con un objeto const, pero no se recomienda el uso de punteros a objetos const debido a posibles problemas con la corrección constante.</mydata*>

Comments are closed.