Si j'ai du code où j'aimerais utiliser autant que possible les extensions C++ 11x, mais j'ai un repli si ce n'est pas pris en charge. Actuellement, la version OSX de GCC et le compilateur VisualC ont peu ou pas de support pour C++ 11x, donc j'utilise:
#if (defined(__Apple__) || (defined(_WIN32)))
...fallback code without C++11x ...
#else
... code using C++11x ...
#endif
Et cela fonctionne, mais ce n'est pas vraiment la bonne chose à faire, d'autant plus que le compilateur gcc dans MacPorts prend en charge c ++ 11x.
Y a t-il #define C11X_SUPPORTED
macro de type? Peut-être quelque chose que seul GCC possède?
__cplusplus
doit être défini comme 199711L
dans les compilateurs pré-C++ 11, 201103L
dans ceux qui supportent C++ 11. Que cela aide beaucoup dans la pratique est une autre question: la plupart des compilateurs ne sont qu'à mi-chemin, il ne faut donc pas le définir comme 201103L
, même s'ils prennent en charge les fonctionnalités qui vous intéressent. Et il n'est pas rare qu'un compilateur ment: un compilateur qui le définit comme 199711L
et ne prend pas en charge export
pour les modèles, par exemple. Mais il n'y a pas de test standard de fonctionnalité par fonctionnalité.
La solution la plus simple consiste simplement à ne pas utiliser de nouvelle fonctionnalité particulière jusqu'à ce que vous soyez sûr que tous les compilateurs la prennent en charge. Vous devez quand même écrire et prendre en charge le code de secours; pourquoi maintenir deux versions. La seule exception à cette règle peut être les nouvelles fonctionnalités qui ont un impact sur les performances: que le compilateur prenne en charge les sémantiques de déplacement ou non. Dans de tels cas, je suggère un fichier include dépendant du compilateur, que vous écrivez vous-même en fonction de la documentation du compilateur et des tests personnels; ce n'est pas parce que le compilateur peut documenter qu'il prend en charge une fonctionnalité spécifique que son support est exempt de bogues. Créez simplement un répertoire par compilateur ciblé, placez-y ce fichier et spécifiez le -I
ou /I
option dans votre fichier makefile ou projet.
Et vos tests devraient être quelque chose comme:
#ifdef HAS_MOVE_SEMANTICS
...
#endif
plutôt que sur le compilateur, la version ou autre.
Vous pouvez vérifier la valeur de __cplusplus
macro. Pour C++ 11, il est supérieur à 199711L
.
Donc quelque chose comme
#if __cplusplus > 199711L
#endif
La bibliothèque Boost.Config fournit macros de préprocesseur granulaire que vous pouvez utiliser pour compiler conditionnellement en fonction de la présence d'une fonctionnalité C++ 11 donnée.
(Pour un compilateur, la prise en charge de C++ 11 n'a pas besoin d'être une proposition tout ou rien. Par exemple, réfléchissez à la manière dont Microsoft choisi parmi les fonctionnalités de C++ 11 à inclure dans Visual Studio 2012 en fonction de ce qu'il croyaient que ce serait le plus avantageux pour leurs clients.)