Es posible escribir una función que, cuando se compila con un compilador de C, devolverá 0, y cuando se compila con un compilador de C ++, devolverá 1 (la solución trivial con
#ifdef __cplusplus
no es interesante).
Por ejemplo:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Por supuesto, lo anterior funcionará solo si sizeof (char)
no es lo mismo quesizeof (int)
Otra solución más portátil es algo como esto:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
No estoy seguro de si los ejemplos son 100% correctos, pero entiendes la idea. Creo que también hay otras formas de escribir la misma función.
¿Qué diferencias, si las hay, entre C ++ 03 y C ++ 11 se pueden detectar en tiempo de ejecución? En otras palabras, ¿es posible escribir una función similar que devuelva un valor booleano que indique si está compilada por un compilador C ++ 03 conforme o un compilador C ++ 11?
bool isCpp11()
{
//???
}
fuente
Respuestas:
Lenguaje principal
Accediendo a un enumerador usando
::
:También puede abusar de las nuevas palabras clave
Además, el hecho de que los literales de cadena ya no se conviertan en
char*
Sin embargo, no sé qué tan probable es que esto funcione en una implementación real. Uno que explota
auto
Lo siguiente se basa en el hecho de que
operator int&&
es una función de conversión aint&&
en C ++ 0x, y una conversión aint
seguida de lógica y en C ++ 03Ese caso de prueba no funciona para C ++ 0x en GCC (parece un error) y no funciona en el modo C ++ 03 para clang. Se ha archivado un clang PR .
El tratamiento modificado de los nombres de clases inyectados de plantillas en C ++ 11:
Se pueden usar un par de "detectar si esto es C ++ 03 o C ++ 0x" para demostrar cambios importantes. El siguiente es un caso de prueba modificado, que inicialmente se usó para demostrar tal cambio, pero ahora se usa para probar C ++ 0x o C ++ 03.
Biblioteca estándar
Detectando la falta de
operator void*
en C ++ 0x 'std::basic_ios
fuente
true
para MSVC 2005 en adelante, y un error de compilación en MSVC 2003.(...)
vs.(char*)
¡Realmente me gusta eso!Me inspiré en ¿Qué cambios importantes se introducen en C ++ 11? :
Esto se basa en los nuevos literales de cadena que tienen prioridad sobre la expansión de macros.
fuente
#undef u8
entonces el uso del preprocesador solo es observable si su programa tiene una macro previamente definida llamadau8
(boooo). Si eso es una preocupación real, aún se puede solucionar usando pragmas / llamadas de macro push / pop específicos de la implementación (la mayoría de las implementaciones tienen estos, creo).¿Qué tal un cheque usando las nuevas reglas para
>>
cerrar plantillas?Alternativamente, una comprobación rápida de
std::move
:fuente
std::move
?A diferencia de C ++ anterior, C ++ 0x permite crear tipos de referencia a partir de tipos de referencia si ese tipo de referencia base se introduce mediante, por ejemplo, un parámetro de plantilla:
El reenvío perfecto tiene el precio de romper la compatibilidad con versiones anteriores, desafortunadamente.
Otra prueba podría basarse en tipos locales ahora permitidos como argumentos de plantilla:
fuente
isC++0x
es un identificador C ++ válido;)Este no es un ejemplo del todo correcto, pero es un ejemplo interesante que puede distinguir C de C ++ 0x (aunque C ++ 03 no es válido):
fuente
sizeof(int) != 1
ser verdad. En un sistema 0x conchar
s excepcionalmente grandes , los resultados podrían ser los mismos. Sin embargo, sigue siendo un buen truco.char
aunque siempre es un bytesizeof(char)
siempre será 1, por definición. PeroCHAR_BIT
(definido en limits.h) se permite que sea más de 8. Como resultado, amboschar
yint
podrían tener 32 bits, en cuyo casosizeof(int) == 1
(yCHAR_BIT == 32
).De esta pregunta :
fuente
bool is_cpp0x = !test[0].flag;
T
mientras que C ++ 03 copia construcciones deT()
Aunque no es tan conciso ... En C ++ actual, el nombre de la plantilla de clase en sí se interpreta como un nombre de tipo (no un nombre de plantilla) en el alcance de esa plantilla de clase. Por otro lado, el nombre de la plantilla de clase se puede usar como un nombre de plantilla en C ++ 0x (N3290 14.6.1 / 1).
fuente
fuente