7
votes

Déterminer l'existence du temps de compilation d'inclure des fichiers en C ++

J'essaie d'écrire un code de bibliothèque portable C ++ qui s'appuiera initialement sur Boost.regex, puis de passer à TR1 car les compilateurs le supportent et éventuellement à la spécification C ++ 0X après que les choses se sont déplacées du STD: : Espace de noms TR1 à STD. Voici un peu de pseudo-code pour ce que j'aimerais faire avec le préprocesseur:

if( exists(regex) )    // check if I can #include <regex>
{
    #include <regex>    // per TR1
    if( is_namespace(std::tr1) )   // are we on TR1 or C++0x?
    {
        using std::tr1::regex;
    } else
    {
        using std::regex;
    }
} else    // fall-back to boost
{
    #include <boost/regex.hpp>
    using boost::regex;
}


0 commentaires

4 Réponses :


6
votes

Vous ne pouvez pas le faire. La phase de prétraitement de C ++ arrive avant la phase de compilation, de sorte que les constructions conditionnelles de langue C ++ ne peuvent donc pas être placées utilement autour des directives de préprocesseur telles que #include.

Si vous avez besoin de compilation conditionnelle, la façon de le faire est d'utiliser #Ifdef. Quelque chose comme: xxx

où boost_build est un symbole de préprocesseur que vous définissez dans votre maquillage ou autre.


2 commentaires

J'ai spécifiquement dit que je n'essayais pas d'utiliser des constructions conditionnelles compilées C ++. Plus spécifiquement, je cherche quelque chose de similaire à une directive #Ifdef qui a la fonctionnalité de la vérification si le fichier incluant existe: #IFexists (ou quelque chose à cet effet)


Il n'y a pas de fonctionnalité de préprocesseur de ce type. Si vous avez vraiment besoin de faire cela 9 et je doute que vous le feriez), vous devez exécuter votre code à travers une sorte de script de traitement de texte écrit dans quelque chose comme Perl ou Python avant de le compiler.



10
votes

Vous ne pouvez pas le faire sans compter sur une troisième chose avant le prétraitement . Généralement, des choses comme autoconf peuvent être utilisées pour y accomplir.

Ils fonctionnent en générant un autre fichier d'en-tête avec #define des directives indiquant l'existence d'en-têtes / bibliothèques que vous souhaitez utiliser.


1 commentaires

Merci pour la clarification! :)



4
votes

Vous pouvez utiliser la macro code> __ cplusplus code> pour voir la version de C ++ avec laquelle vous travaillez, dans la norme suivante (C ++ 1x, C ++ 0x n'est pas censé être ) Il aura une valeur supérieure à 199711L

#if __cplusplus > 199711
    using std::regex;
#else
    using std::tr1::regex;
#endif


0 commentaires

2
votes

Mise à jour de ce sujet au cas où vous recevez ce problème récemment: Maintenant, cela est possible avec C ++ 17, utilisez le préprocesseur macro __has_include () xxx

détails ici:

https://fr.cppreference.com/w/cpp/preprocessor/include


0 commentaires