Pergunta

Eu tentando incorporar um registro de erros simples em meu aplicativo existente, no momento em que ele relata erros apenas usando cout então eu estava esperando para manter uma interface similar usando o operador <<. No entanto eu quero-o para registrar a linha e funcionar ocorreu o erro, mas eu não quero ter que digitar __LINE__, __FUNCTION__ cada vez que eu precisa fazer login. Alguém sabe um truque que eu posso usar para permitir que a macro __LINE__ para ser usado dentro de outra função, relatando a linha de chamada em vez disso? Esperança que faz sentido.

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

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

Em vez de isso toda vez

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

Gostaria de apenas ser capaz de fazer:

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;
}
Foi útil?

Solução

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

Com o seu encadeamento operator << não irá funcionar uma vez que retorna um bool.

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

É habitual para definir inserção de fluxo como se segue:

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

Faça o seguinte:

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

Além disso, você pode quebrar a macro em um loop do-while:

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

Em seguida, você pode facilmente escrever:

 myLogClass myLogger; // do this

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

Outras dicas

Em ANSI C (que também devem trabalhar em C ++ Eu suponho), você pode fazer isso usando funções e pré-processamento macros variádicos. Veja o exemplo abaixo:

#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;
}

Não, é por isso que o registo é feito com macros. necessidades __LINE__ ser expandida pelo pré-processador na linha em questão, não de uma função de registro comum.

Como Adam Mitz mencionado você precisa usar __LINE__ no lugar de chamada.
Eu recomendo que você adicione um parâmetro extra como "AdditionalInfo" e criar uma macro que irá gerar esse "AdditionalInfo" usando __LINE__ e __FUNCTION __.

Eu não poderia obter o código na primeira resposta para compilar. Eu uso essa macro simples que realiza a tarefa bem:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top