2009-09-08 11 views
17

Tengo el problema de que, std :: numeric_limits :: min() entra en conflicto con la macro "min" definida en "windef.h". ¿Hay alguna manera de resolver este conflicto sin definir la macro "min"? El siguiente enlace proporciona algunos consejos, sin embargo, no pude lograr el uso de paréntesis con una función de miembro estática.macro y conflicto de función de miembro

What are some tricks I can use with macros?

gracias de antemano.

+8

¿Por qué el truco de paréntesis no funciona para usted? Recuerde envolverlo alrededor de la expresión completa, como en '(std :: numeric_limits :: min)()' –

+0

Esto funcionó. Gracias. Por favor envíela como respuesta, me gustaría aceptarla. – msh

+0

Muchas gracias, no puedo creer que haya estado dando vueltas con # undef durante años antes de que alguien mencionara esto ... – Roel

Respuesta

29

La solución consiste en utilizar el paréntesis: int max = (numeric_limits<int>::max)();

Se permite la inclusión windef.h, no requiere #undef max (que puede tener efectos secundarios adversos) y no es necesario #define NONIMAX. ¡Funciona de maravilla!

+0

¿Puedes explicar por qué funciona esto? – Derek

+1

Por lo que entiendo, procesa primero el valor entre paréntesis. la macro también toma dos parámetros y, al encerrar el paréntesis de la función, no mostrará ningún parámetro en la macro. – Apeiron

1

Sí, he encontrado el mismo problema. Encontré una sola solución:

#ifdef min 
#undef min 
#endif //min 

Colóquelo justo después de que lo haya hecho.

+2

Tenga en cuenta que el '# ifdef' es innecesario. Está bien para '# undef' un nombre que no está definido como macro, por lo que' #undef min' es seguro, independientemente de si se define 'min'. –

23

La única solución realmente general es que no incluye windows.h en sus encabezados.

Ese encabezado es un asesino, y hace prácticamente todo lo que puede para que su código explote. No se compilará sin las extensiones de lenguaje MSVC habilitadas, y es el peor ejemplo de abuso de macro que he visto en mi vida.

Inclúyalo en un solo archivo .cpp, y luego exponer las envolturas en un encabezado, que el resto de su código puede usar. Si windows.h no está visible, no puede entrar en conflicto con sus nombres.

Para la caja min/max específicamente, puede #define NOMINMAX antes de incluir windows.h. No definirá esas macros específicas.

+1

Votado, ya que llegamos a la misma conclusión aquí. Entre otros males, agrega aproximadamente 19K * por archivo de objeto *. Acabamos de crear nuestro propio archivo de encabezado con las pocas cosas que normalmente necesitamos de windows.h en él. –

+2

Buena respuesta.No sabía acerca de ese truco de 'NOMINMAX'. –

+6

Bueno, es una solución típica de Microsoft ... "¿Nuestras macros están causando problemas? Bueno, ¡simplemente agregaremos una macro para deshabilitarlas!" ;) – jalf

1

Además de la respuesta de jalf, también puede #define WINDOWS_LEAN_AND_MEAN antes de incluir windows.h. Se eliminará el mínimo, máximo y un poco más de ruido de los encabezados de Windows.

+0

Gracias. Sin embargo, en mi proyecto, eso causa mucho más dolor de cabeza. – msh

1

Dewfy, El problema con esa solución es si no necesita utilizar los macropaneles.

Incluso probé la definición de NOMINMAX pero no funcionó.

La mejor solución que encontré fue el de Johannes Schaub: (std :: :: numeric_limits min)()

0
#define NOTHING 

int main() 
{ 
    int m = -1; 

    m = max(0, 1); // expands max macro 

    m = max NOTHING (0, 1); // error 'max': identifier not found 
          // functions-like macros are defined as an 
          // identifier immediately followed by a left 
          // parenthesis - N3690/16.3/10 

    m = std::max NOTHING (2, 3); // NOTHING stops the macro 
           // expansion (max is not followed by left 
           // parenthesis): std::max is called 

    m = (std::max)(4, 5); // the enclosing parenthesis stops the macro 
          // expansion (max is not followed by left 
          // parenthesis): std::max is called 

    return 0; 
} 
Cuestiones relacionadas