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
Boost.Config a ne multitude de macros qui peut être utilisé pour tester la prise en charge de fonctionnalités spécifiques à C++ 11.
Il y a une constante nommée __cplusplus
que les compilateurs C++ doivent définir sur la version de la norme C++ prise en charge voir ceci
#if __cplusplus <= 199711L
#error This library needs at least a C++11 compliant compiler
#endif
Il est défini sur 199711L dans Visual Studio 2010 SP1, mais je ne sais pas si les fournisseurs seront si audacieux de l'augmenter déjà s'ils ne disposent que d'une prise en charge (partielle) au niveau du compilateur par rapport à une bibliothèque C++ standard avec toutes les modifications apportées à 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, une prise en charge des threads C++ 11 et d'autres parties spécifiques de la norme.
Comme indiqué par le C++ 11 standard (§iso.16.8):
Le nom __ cplusplus est défini à la valeur 201103L lors de la compilation d'une unité de traduction C++.
Avec la valeur de cette macro, vous pouvez vérifier si le compilateur est conforme à 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’existe aucun moyen standard, portable; vous pouvez consulter la documentation du compilateur ou les fichiers d'en-tête de la bibliothèque std pour obtenir plus d'informations.
Je sais que c'est une très vieille question, mais cette question peut être souvent vue et les réponses sont un peu dépassées.
Les nouveaux compilateurs avec le standard 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 avec #ifdef
. Par exemple, pour vérifier les littéraux définis par l'utilisateur, vous pouvez utiliser
#ifdef __cpp_user_defined_literals
Pour vérifier le support C++ 14 et autres. Test sur GCC 5.2.1.
#include <iostream>
int main(){
#if __cplusplus==201402L
std::cout << "C++14" << std::endl;
#Elif __cplusplus==201103L
std::cout << "C++11" << std::endl;
#else
std::cout << "C++" << std::endl;
#endif
return 0;
}
Je viens d'écrire une petite suite de tests pour vérifier quelles fonctionnalités de C++ 11 sont prises en charge par un compilateur spécifique. Cependant, il s’agit bien entendu d’une vérification "pré-compilation".
Vous pouvez utiliser ceci:
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
cout << "C++11 is supported";
#else
cout << "C++11 is not supported";
#endif
Pour C++ 11, la plupart des compilateurs sauf Visual Studio définissent le __cplusplus
macro à 201103L
, mais toute version de Visual Studio le définit à 199711L
qui est la valeur utilisée pour les autres compilateurs avant C++ 11. Ce code compare le _cplusplus
macro avec 201103L
pour tous les compilateurs sauf Visual Studio, et si le compilateur est Visual Studio, il vérifie si la version de Visual Studio est ulté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 valeur 1900
, voir cette réponse ).
Si vous ne souhaitez pas utiliser Boost.Config et devez rechercher les compilateurs prenant en charge C++ 11, vérifiez la valeur de la constante __cplusplus
ça ira. Cependant, un compilateur peut prendre en charge la plupart des fonctionnalités populaires de la norme C++ 11, sans toutefois prendre en charge l'intégralité des spécifications. Si vous souhaitez activer la prise en charge de compilateurs Visual Studio spécifiques qui ne sont pas encore entièrement conformes aux spécifications C++ 11, utilisez l'extrait de code suivant, qui permet la compilation dans Visual Studio 2013:
#if defined(_MSC_VER)
# if _MSC_VER < 1800
# error This project needs atleast Visual Studio 2013
# endif
#Elif __cplusplus <= 199711L
# error This project can only be compiled with a compiler that supports C++11
#endif
Une liste complète des versions du compilateur pour Visual Studio est fournie à Comment détecter si je compile du code avec Visual Studio 2008
Dans le monde traditionnel Linux/Unix, autoconf est traditionnellement utilisé pour tester la présence de bibliothèques, de fonctionnalités de compilateur et de bogues, en les plaçant dans un fichier config.h que vous utilisez dans vos fichiers selon vos besoins.
Lorsque votre vérification concerne la disponibilité d'une bibliothèque C++ 11 (et non une fonctionnalité de langage), par exemple l'en-tête <array>
, Vous pouvez #if __has_include(<array>)
.
Parfois, vérifier #if __cplusplus >= 201103L
Vous indiquerait que vous utilisez C++ 11, mais d’autres paramètres tels que le paramètre de version de bibliothèque standard dans Xcode peuvent toujours ne pas disposer des nouvelles bibliothèques disponibles (la plupart d’entre elles sont disponibles sous des noms différents, par exemple <tr1/array>
)