2010-05-30 6 views
5

Quelles sont les meilleures pratiques pour l'utilisation autoconf conjointement avec shared_ptr et autres C TR1/BOOST ++ modèles 0x de manière à maximiser la portabilité et maintenabilité?Comment utiliser autoconf avec C++ 0x fonctionnalités

Avec autoconf je peux déterminer si shared_ptr est disponible std::tr1::shared_ptr et/ou boost::shared_ptr. Étant donné que la même caractéristique a deux noms différents, je les questions suivantes:

  1. Dans le code, comment devrait shared_ptr être référencé?
  2. Devrait-on préférer std::tr1::shared_ptr par rapport à boost::shared_ptr?

Pour la première, le code utilise actuellement conditionals préprocesseur permettant des références non qualifiées à shared_ptr, à la

#if HAVE_STD_TR1_SHARED_PTR 
using std::tr1::shared_ptr; 
#elif HAVE_BOOST_SHARED_PTR 
using boost::shared_ptr; 
#else 
#error "No definition for shared_ptr found" 
#endif 

En second lieu, le code utilise std::tr1:: sur boost:: pour minimiser dépendances sur les bibliothèques externes (même si les bibliothèques sont largement utilisées).

Ces deux solutions sont-elles courantes? Y en a-t-il de meilleurs?

Répondre

3

Une amélioration à votre code d'exemple, et une réponse à votre première question, est d'utiliser l'idiome « ​​template typedef »:

#if HAVE_STD_TR1_SHARED_PTR 
    template <class T> 
    struct SharedPtr { 
     typedef std::tr1::shared_ptr<T> Type; 
    }; 
#elif HAVE_BOOST_SHARED_PTR 
    template <class T> 
    struct SharedPtr { 
     typedef boost::shared_ptr<T> Type; 
    }; 
#else 
# error "No definition for shared_ptr found" 
#endif 

// Declare a shared_ptr using our wrapper classes, saving us from having to care 
// where shared_ptr comes from: 
SharedPtr<int>::Type my_shared_int(new int(42)); 

Le principal problème avec ceci est la nécessité d'utiliser la :: notation Type . C'est purement parce que C++ n'a actuellement aucun moyen d'avoir un typedef pour un template. Vous pouvez avoir un typedef pour un type de template instance, mais il est important ici que nous conservions la généricité. Quant à savoir si vous préférez TR1 à Boost, je dirais oui. Maintenant que les compilateurs sont livrés avec un support C++ 0x partiel, je dirais que vous devriez aussi tester std :: shared_ptr et préférer ça à l'un ou l'autre des autres.

Vous pourriez avoir besoin d'un quatrième typedef s'il y a des compilateurs qui ont un shared_ptr ailleurs. Je ne connais pas un tel compilateur, mais un peu de code C++ que je maintiens fait quelque chose de similaire à ce que vous demandez avec l'extension commune slist à la bibliothèque C++ standard, pour les listes à lien unique. Les anciennes versions de g ++ le placent dans un espace de nom global, le g ++ moderne le place dans l'espace de noms __gnu_cxx spécifique au compilateur, et nous en avons même trouvé un qui le met par erreur dans std!

+0

Je ne vois pas ce que votre modèle typedef ajoute au-delà de la suggestion de l'auteur original. Il a "pollué" les choses avec shared_ptr . Vous avez pollué des choses avec SharedPtr :: Type. Les deux semblent équivalents, et le sien implique moins de dactylographie. Que fait votre template typedef au-delà de l'instruction using dans le message d'origine? –

+0

Vous l'atteignez: vous n'avez plus besoin de hisser ces noms dans l'espace de noms global. Ma méthode n'ajoute pas nécessairement de noms globaux. vous pouvez l'espace de noms si vous le souhaitez. Et si vous ne le faites pas, le mien est beaucoup moins susceptible d'entrer en conflit avec les noms d'une autre bibliothèque. –

+0

Étant donné que shared_ptr sera éventuellement dans std :: et qu'autoclonf peut déterminer dans quel namespace shared_ptr est défini, je penche vers "namespace std {using :: shared_ptr;}" s'il n'y a pas std :: shared_ptr défini. – themis

Questions connexes