web-dev-qa-db-fra.com

Comment vérifier le support C ++ 11?

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
97
Maxpm

Boost.Config a ne multitude de macros qui peut être utilisé pour tester la prise en charge de fonctionnalités spécifiques à C++ 11.

54
James McNellis

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.

117
Cygon

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.

37
Paolo M

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
31
Jarryd

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;
}
20
kurono267

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".

https://github.com/sloede/cxx11tests

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 ).

15
Donald Duck

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

7
Vamshi Krishna

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.

6
diverscuba23

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>)

1
yairchu