Pregunta

Intento incorporar un registro de error simple en mi aplicación existente, en este momento informa de errores simplemente usando cout, así que esperaba mantener una interfaz similar usando el operador <<. Sin embargo, quiero que registre la línea y funcione, se produjo el error, pero no quiero tener que escribir __LINE__, __FUNCTION__ cada vez que necesito iniciar sesión. ¿Alguien sabe un truco que pueda usar para permitir que la macro __LINE__ se use dentro de otra función, informando la línea de llamada? Espero que tenga sentido.

class myLogClass {
    uint8_t level;                  
public:                 
    bool operator<<( const char * input );          
};

bool myLogClass::operator<<( const char * input ) {
    logItInSQL( input );
    return true;
}

En lugar de esto cada vez

myLogClass << "Line No: " << __LINE__
    << " Function: " << __FUNCTION__
    << " Error: " << "This is my error to be logged";

Me gustaría poder hacer:

myLogClass << "This is my error to be logged";

bool myLogClass::operator<<( const char * input ) {
    logItInSQL( " Line No: __LINE__" );
    logItInSQL( " Function: __FUNCTION__" );
    logItInSQL( " Error: " + input );
    return true;
}
¿Fue útil?

Solución

myLogClass << "Line No: " << __LINE__ ...

Con su operator << encadenamiento no funcionará ya que devuelve un bool.

bool myLogClass::operator << (const char * input)

Es habitual definir la inserción de la secuencia de la siguiente manera:

std::ostream& myLogClass::operator << (std::ostream& o, const char * input) {
    // do something
    return o;
}

Haz esto:

#define log(o, s) o << "Line No: " << __LINE__ << \
                   " Function: " << __FUNCTION__ << \
                   " Error: " << s // note I leave ; out

Además, puede ajustar la macro en un bucle do-while:

#define log(o, s) do { o << "Line No: " << __LINE__ << \
                   " Function: " << __FUNCTION__ << \
                   " Error: " << s; \ 
                  } while(0) // here, I leave ; out

Entonces puedes escribir felizmente:

 myLogClass myLogger; // do this

 // use it
log(myLogger, "This is my error to be logged"); // note the ;

Otros consejos

En ANSI C (que también debería funcionar en C ++, supongo), puede hacerlo utilizando funciones variadas y macros de preprocesador. Vea el ejemplo a continuación:

#include <stdio.h>
#include <stdarg.h>

#define MAXMSIZE 256
#define MyDebug(...) MyInternalDebug(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__)

void MyInternalDebug( char *file, char *function, const int line, const char *format, ... )
{
    char message[MAXMSIZE];
    // Variable argument list (VA)
    va_list ap;
    // Initialize VA
    // args : Name of the last named parameter in the function definition.
    // The arguments extracted by subsequent calls to va_arg are those after 'args'.
    va_start(ap, format);

    // Composes a string with the same text that would be printed if 'format' was used on printf,
    // but using the elements in the variable argument list identified by 'ap' instead of
    // additional function arguments and storing the resulting content as a C string in the buffer pointed by 'message'.
    // * The state of arg is likely to be altered by the call.
    vsprintf(message, format, ap);
    // Custom print function
    printf("%s\t%s\t%d\t%s\n",file, function, line, message);

    // Finzalize use of VA
    va_end(ap);
}

int main ()
{  
    MyInternalDebug(__FILE__, __FUNCTION__, __LINE__, "An error occured with message = '%s'", "Stack Overflow");
    MyDebug("Another error occured with code = %d", 666);

    return 0;
}

No, esta es la razón por la cual el registro se realiza con macros. __LINE__ necesita ser expandido por el preprocesador en la línea en cuestión, no en una función de registro común.

Como Adam Mitz mencionó, debe usar __LINE__ en el lugar de la llamada.
Le recomiendo que agregue un parámetro adicional como & Quot; AdditionalInfo & Quot; y cree una macro que generará este " AdditionalInfo " usando __LINE__ y __FUNCTION__.

No pude obtener el código en la primera respuesta para compilar. Utilizo esta macro simple que cumple bien la tarea:

#define qlog(s) std::cerr << __FUNCTION__ << "::" << __LINE__ << "\t" << s << endl

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