Il est possible d'écrire une fonction qui, lorsqu'elle est compilée avec un compilateur C retournera 0, et lorsqu'elle sera compilée avec un compilateur C ++, retournera 1 (la solution triviale avec
#ifdef __cplusplus
n'est pas intéressante).
Par exemple:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Bien sûr, ce qui précède ne fonctionnera que si ce sizeof (char)
n'est pas la même chose quesizeof (int)
Une autre solution plus portable est quelque chose comme ceci:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
Je ne sais pas si les exemples sont corrects à 100%, mais vous comprenez l'idée. Je pense qu'il existe également d'autres façons d'écrire la même fonction.
Quelles différences, le cas échéant, entre C ++ 03 et C ++ 11 peuvent être détectées au moment de l'exécution? En d'autres termes, est-il possible d'écrire une fonction similaire qui retournerait une valeur booléenne indiquant si elle est compilée par un compilateur C ++ 03 conforme ou un compilateur C ++ 11?
bool isCpp11()
{
//???
}
la source
Réponses:
Langue de base
Accéder à un énumérateur en utilisant
::
:Vous pouvez également abuser des nouveaux mots clés
De plus, le fait que les littéraux de chaîne ne se convertissent plus en
char*
Je ne sais pas dans quelle mesure vous avez des chances que cela fonctionne sur une implémentation réelle. Celui qui exploite
auto
Ce qui suit est basé sur le fait qu'il
operator int&&
s'agit d'une fonction de conversionint&&
en C ++ 0x, et d'une conversion enint
suivi de logique et en C ++ 03Ce cas de test ne fonctionne pas pour C ++ 0x dans GCC (ressemble à un bogue) et ne fonctionne pas en mode C ++ 03 pour clang. Un clang PR a été déposé .
Le traitement modifié des noms de classe injectés des modèles en C ++ 11:
Un couple de "détecter s'il s'agit de C ++ 03 ou C ++ 0x" peut être utilisé pour illustrer les changements de rupture. Ce qui suit est un cas de test modifié, qui a initialement été utilisé pour démontrer un tel changement, mais est maintenant utilisé pour tester C ++ 0x ou C ++ 03.
Bibliothèque standard
Détecter le manque de
operator void*
C ++ 0x 'std::basic_ios
la source
true
pour MSVC 2005 et une erreur de compilation dans MSVC 2003.(...)
vs(char*)
calls. J'aime beaucoup ça!Je me suis inspiré de Quels changements de rupture sont introduits dans C ++ 11? :
Ceci est basé sur les nouveaux littéraux de chaîne qui ont priorité sur l'expansion de macro.
la source
#undef u8
alors l'utilisation du préprocesseur n'est observable que si votre programme a une macro précédemment définie nomméeu8
(boooo). Si c'est un problème réel, cela peut toujours être contourné en utilisant des pragmas / appels de macro push / pop spécifiques à l'implémentation (la plupart des implémentations en ont, je crois).Que diriez-vous d'un chèque en utilisant les nouvelles règles de
>>
fermeture des modèles:Alternativement, une vérification rapide pour
std::move
:la source
std::move
?Contrairement au C ++ précédent, C ++ 0x permet de créer des types de référence à partir de types de référence si ce type de référence de base est introduit, par exemple, via un paramètre de modèle:
Une transmission parfaite se fait malheureusement au prix de la rupture de la rétrocompatibilité.
Un autre test pourrait être basé sur des types locaux désormais autorisés comme arguments de modèle:
la source
isC++0x
c'est un identifiant C ++ valide;)Ce n'est pas un exemple tout à fait correct, mais c'est un exemple intéressant qui peut distinguer C vs C ++ 0x (c'est cependant C ++ 03 invalide):
la source
sizeof(int) != 1
être vrai. Sur un système 0x avec deschar
s exceptionnellement grands , les résultats pourraient être les mêmes. Encore un truc sympa, cependant.char
est toujours un octetsizeof(char)
sera toujours 1, par définition. MaisCHAR_BIT
(défini dans limits.h) est autorisé à être supérieur à 8. En conséquence, les deuxchar
etint
pourraient avoir 32 bits, auquel cassizeof(int) == 1
(etCHAR_BIT == 32
).De cette question :
la source
bool is_cpp0x = !test[0].flag;
T
alors que la copie de C ++ 03 construit deT()
Bien que pas si concis ... Dans le C ++ actuel, le nom du modèle de classe lui-même est interprété comme un nom de type (pas un nom de modèle) dans la portée de ce modèle de classe. D'autre part, le nom de modèle de classe peut être utilisé comme nom de modèle dans C ++ 0x (N3290 14.6.1 / 1).
la source
la source