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.

Método de impresión para pares de plantillas variádicas en C++

Quiero lograr algo como:
cpp
export_vars("ruta/al/archivo.dat", {"nombre_variable", obj}, {"otra_variable", 2});

donde obj puede ser cualquier tipo siempre y cuando tenga una sobrecarga << – la idea es escribir en un ofstream más adelante. He intentado (para una initializer_list de pares):
cpp
void
export_vars(const std::string& ruta, std::initializer_list<std::pair<std::string, std::any>> args)
{
for (auto& [nombre, var] : args)
std::cout << nombre << ": " << var << std::endl;
}

pero std::any no puede ser << sin conocer el tipo subyacente. ¿Se puede lograr usando plantillas variadic y expansión de paquetes de parámetros? También intenté algo como:
cpp
template <class... Args>
void
export_vars(const std::string& ruta, Args... args)
{
(std::cout << ... << args.first << args.second) << std::endl;
}

pero eso obviamente está mal. ¿Alguna sugerencia?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que necesita una forma de imprimir una variedad de tipos de variables en un ofstream. Una solución posible es usar plantillas variáticas y expansión de paquetes de parámetros para procesar recursivamente cada argumento e imprimir su nombre y valor. Aquí hay un ejemplo de implementación:

    #include <fstream>
    #include <utility>
    
    template <typename t="">
    void output_arg(std::ofstream& file, const std::string& name, const T& arg)
    {
        file << name << ": " << arg << std::endl;
    }
    
    template <typename t,="" typename...="" rest="">
    void output_arg(std::ofstream& file, const std::string& name, const T& arg, Rest&&... rest)
    {
        output_arg(file, name, arg);
        output_arg(file, std::forward<rest>(rest)...);
    }
    
    template <typename... args="">
    void export_vars(const std::string& path, Args&&... args)
    {
        std::ofstream file(path);
        output_arg(file, std::forward<args>(args)...);
    }
    

    Esta implementación utiliza dos funciones: output_arg y export_vars.

    output_arg toma un ofstream, una cadena name y un argumento de cualquier tipo. Imprime el nombre y el argumento en el archivo. Si el argumento no se puede transmitir por secuencia, el programa no se compila.

    export_vars toma una cadena path y un número variable de argumentos. Cuando se llama, crea un objeto ofstream con la ruta de archivo especificada y pasa sus argumentos a output_arg usando la expansión de paquetes de parámetros.

    Para usar esta implementación, llamaría a export_vars con cualquier número de pares de argumentos de este modo:

    export_vars("path/to/file.dat", "variable_name", obj, "another_variable", 2);
    

    Esto creará un objeto ofstream para el archivo en la ruta especificada, imprimirá el nombre y el valor de obj bajo el nombre "variable_name", e imprimirá el nombre "another_variable" con el valor 2.

    Tenga en cuenta que esta implementación asume que todos los argumentos tienen nombres únicos; si varios argumentos tienen el mismo nombre, solo se imprimirá el último en el archivo. También supone que el archivo se puede abrir y escribir; si el archivo no se puede abrir ni escribir, el programa fallará silenciosamente.</typename…>

Comments are closed.