2010-02-24 11 views
6

Actualmente utilizo la siguiente plantilla simplemente como una forma de verificar el puntero NULL y si es NULO, entonces imprimo un mensaje de error en un archivo de registro y luego devuelvo falso.Pasar la variable "nombre" en C++

template< typename T > 
static bool isnull(T * t, std::string name = "") 
{ 
    _ASSERTE(t != 0); 
    if(!t) 
    { 
     if(!(name.length())) name = "pointer"; 
     PANTHEIOS_TRACE_ERROR(name + " is NULL"); 
     return false; 
    } 
    return true; 
} 

Actualmente Yo llamo a esto de la siguiente manera:

if(!(isnull(dim, BOOST_STRINGIZE(dim)))) return false; 

Si nota que necesito para pasar en el "nombre" del puntero variable que quiero imprimir el archivo de registro, como el 2º parámetro. Actualmente estoy usando BOOST_STRINGIZE que simplemente convierte cualquier texto entre paréntesis en una cadena.

Las siguientes son las desventajas de mi implementación de plantilla (para mi uso al menos)

  • Cualquiera podía pasar nada como parámetro para BOOST_STRINGIZE para imprimir en el archivo de registro - desde los 2 parámetros no están relacionados de de todos modos, entonces no necesariamente vería el "nombre de variable" que en realidad es NULL
  • Tenemos que recordar pasar el segundo parámetro, sino inútil.

¿De todos modos puedo tener el "nombre" de esa primera variable que se determina automáticamente, de modo que puedo omitir pasarlo, como el 2º parámetro, con cada llamada?

+1

A menos que hagas magia de preprocesador, no es posible. pero siempre se puede escribir: 'is_null #define (a) isnull ((a), #A)' – lollinus

+1

El segundo problema puede ser resuelto con sólo deshacerse del defecto en el parámetro de nombre. Solo relacionado tangencialmente, usando "name.empty()" podría ser más rápido y/o más claro que "! Name.length()" –

+0

@ Mark-B. Gracias por el comentario "vacío" :). Creo que simplemente asumí que dado que vector.empty() en realidad llama a size() (en la implementación de VC++ 2005) que probablemente sea el mismo para las cadenas. Bad ossandcad. – ossandcad

Respuesta

9

Se puede poner todo en una macro:

#define IS_NULL(name_) isnull(name_, #name_) 

Tenga en cuenta que BOOST_STRINGIZE amplía su argumento si es una macro, que pueden o no ser lo que usted quiere:

#define X(x_) std::cout << BOOST_STRINGIZE(x_) << " = " << x_ << std::endl; 
X(NULL); // prints: "0 = 0" 
+0

Desea una macro stringify como 'BOOST_STRINGIZE', o siempre pasará" name_ ". – GManNickG

+1

¿Cómo es eso, '#' stringifies 'name_'? La diferencia de 'BOOST_STRINGIZE' es solo que expande' name_' si es una macro que no necesariamente considero una ventaja. :) –

+0

Estaba pensando en otra cosa: 3 Mis dos comentarios desaparecerán misteriosamente en un período de tiempo no especificado. – GManNickG

1

Claro, ¿por qué no?

#define new_isnull(x) isnull(x, BOOST_STRINGIZE(x)) 
+0

Gracias. usar # en lugar de BOOST_STRINGIZE fue una ventaja de la respuesta aceptada. – ossandcad

1

La única manera de hacer algo léxicamente así es con las macros. Si siempre desea la impresión correcta, su mejor opción es para envolver toda la declaración en una macro:

//if(!(isnull(dim, BOOST_STRINGIZE(dim)))) return false; 
#define ISNULL(a) isnull((a), #a) 
if (!ISNULL(dim)) return false; 

Tenga en cuenta que, como siempre, las macros tienen una serie de inconvenientes asociados con ellos.

Cuestiones relacionadas