Existe-t-il un moyen de détecter au moment de la compilation si le compilateur prend en charge certaines fonctionnalités de C ++ 11? Par exemple, quelque chose comme ceci:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
template <typename... Test> struct compiler_must_support_variadic_templates;
. Une erreur de syntaxe révélerait rapidement le problème. (EnRéponses:
Il existe une constante nommée
__cplusplus
que les compilateurs C ++ doivent définir sur la version de la norme C ++ prise en charge voir ceciIl est défini sur 199711L dans Visual Studio 2010 SP1, mais je ne sais pas si les fournisseurs seront si audacieux pour l'augmenter déjà s'ils ont juste une prise en charge (partielle) au niveau du compilateur par rapport à une bibliothèque C ++ standard avec toutes les modifications C ++ 11 .
Les définitions de Boost mentionnées dans une autre réponse restent donc le seul moyen sensé de déterminer s'il existe, par exemple, un support pour les threads C ++ 11 et d'autres parties spécifiques de la norme.
la source
__cplusplus
à201103L
. Cela affirme la pleine conformité à la norme 2011; il ne vous informe pas sur la conformité partielle ou les extensions du compilateur. Si__cplusplus
est défini sur201103L
, alors soit le compilateur est entièrement conforme, soit il vous ment. Si ce n'est pas le cas, vous ne pouvez pas vraiment dire quelles fonctionnalités il prend en charge.-std=c++11
option est spécifiée (peut également avec-std=gnu++11
). Ils font cela, même s'ils ne sont pas tout à fait complets (4.8 nous rapproche beaucoup). Remarque - il existe un écart entre ce que le compilateur prend en charge et ce qui est disponible dans la bibliothèque standard. Les versions 4.7.x et 4.8.x ne prennent actuellement pas en charge les regex - mais c'est une bibliothèque, pas une fonctionnalité de compilateur.__cplusplus
sur199711L
pour C ++ 11.__cplusplus
sur199711L
n'est pas un compilateur C ++ 11 conforme. Ils ont probablement des options pour les faire se comporter correctement.Comme indiqué par la norme C ++ 11 (§iso.16.8):
Avec la valeur de cette macro, vous pouvez vérifier si le compilateur est compatible C ++ 11.
Maintenant, si vous cherchez un moyen standard de vérifier si le compilateur prend en charge un sous-ensemble quelconque de fonctionnalités C ++ 11, je pense qu'il n'y a pas de moyen portable standard; vous pouvez consulter la documentation des compilateurs ou les fichiers d'en-tête de la bibliothèque std pour obtenir plus d'informations.
la source
Je sais que c'est une question très ancienne, mais cette question pourrait être souvent vue, et les réponses sont un peu dépassées.
Les nouveaux compilateurs avec la norme C ++ 14 ont un moyen standard de vérifier les fonctionnalités, y compris les fonctionnalités C ++ 11. Une page complète est à https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
En résumé, chaque fonctionnalité a une macro standard définie que vous pouvez vérifier
#ifdef
. Par exemple, pour rechercher des littéraux définis par l'utilisateur, vous pouvez utiliserla source
__has_include()
macro.Pour vérifier le support C ++ 14 et autres. Test sur GCC 5.2.1.
la source
Vous pouvez utiliser ceci:
Pour C ++ 11, la plupart des compilateurs, à l'exception de Visual Studio, définissent la
__cplusplus
macro sur201103L
, mais toute version de Visual Studio la définit à199711L
quelle valeur est utilisée pour les autres compilateurs avant C ++ 11. Ce code compare la_cplusplus
macro avec201103L
pour tous les compilateurs sauf Visual Studio, et si le compilateur est Visual Studio, il vérifie si la version de Visual Studio est postérieure à 2015, la première version de Visual Studio qui prend complètement en charge C ++ 11 (pour Visual Studio 2015, la_MSC_VER
macro a la valeur1900
, voir cette réponse ).la source
g++ -std=c++98
avec GCC 4.8, il s'imprime incorrectementC++11 is supported
.Si vous ne souhaitez pas utiliser Boost.Config et devez tester des compilateurs prenant en charge C ++ 11, alors la vérification de la valeur de la constante
__cplusplus
fera l'affaire. Cependant, un compilateur peut prendre en charge la plupart des fonctionnalités populaires de la norme C ++ 11, mais il ne prend pas en charge toutes les spécifications. Si vous souhaitez activer la prise en charge de compilateurs Visual Studio spécifiques qui ne sont pas encore 100% conformes aux spécifications C ++ 11, utilisez l'extrait de code suivant qui permet la compilation dans Visual Studio 2013:Une liste complète des versions du compilateur pour Visual Studio est fournie sur Comment détecter si je compile du code avec Visual Studio 2008
la source
Dans le monde Linux / Unix traditionnel, autoconf est traditionnellement utilisé pour tester la présence de bibliothèques et de fonctionnalités de compilateur et les bogues en les plaçant dans un fichier config.h que vous utilisez dans vos fichiers si nécessaire.
la source
Lorsque votre vérification porte sur la disponibilité d'une bibliothèque C ++ 11 (pas une fonctionnalité de langage), par exemple l'en-
<array>
tête, vous pouvez#if __has_include(<array>)
.Parfois, la vérification
#if __cplusplus >= 201103L
vous dirait que vous utilisez C ++ 11 mais d'autres paramètres comme le paramètre de version de bibliothèque standard dans Xcode peuvent ne pas avoir les nouvelles bibliothèques disponibles (la plupart d'entre elles sont disponibles sous des noms différents, par exemple<tr1/array>
)la source