2010-09-23 6 views
7

__if_exists est un mot clé spécifique Microsoft pour tester l'existence d'identifiants au moment de la compilation:Existe-t-il un équivalent pour __if_exists dans gnu C++?

msdn:__if_exists

Il peut être très utile à « truqué » spécialisation de modèle que dans certains cas, il fournit vraiment beaucoup plus simple, manière lisible et plus performante que d'autres méthodes comme la "vraie" spécialisation ou la surcharge ou quoi que ce soit.

Mais maintenant, je dois le port d'un grand projet à gnu C++ et je pense que je commencerais un peu de pleurer si je dois trouver d'autres moyens pour les (certes peu) fois je l'ai utilisé

+0

Parlez-vous de #ifdef? http://stackoverflow.com/questions/1802107/define-ifdef-undef-endif – karlphillip

+3

C'est un peu déconcertant de voir "__if_exists'" et "template" au même endroit. Dans tous les cas, s'il n'y a que quelques endroits où il est utilisé, il est probablement préférable de retravailler ces quelques morceaux de code. –

+0

Non, ce n'est pas la même chose que #ifdef, car aveC#ifdef, vous ne pouvez tester que le précompilateur défini par exemple. Les membres de la classe –

Répondre

4

C'est Un mot-clé merdique à mon avis ...

Malheureusement, il n'existe pas dans gcc autant que je sache, mais je ne peux tout simplement pas le savoir.

La bonne façon de gérer cela est de faire appel à Concepts, c'est-à-dire d'adapter les opérations effectuées sur le type en fonction de certaines exigences.

Habituellement, il est réalisé avec traits plutôt que de véritables concepts, car il est plus facile de mettre en place:

template <typename T> 
struct has_dump: boost::mpl::false_ {}; 

Et puis vous débarrasser de vos types de validation de la structure en se spécialisant has_dump.

Le plus simple est de définir 3 méthodes, l'un pour la route, les deux autres pour exécuter les différentes branches:

template <typename T> 
void dump(T& t, boost::mpl::true_ const& dummy) 
{ 
    t.Dump(); 
} 

template <typename T> 
void dump(T& t, boost::mpl::false_ const& dummy) 
{ 
    std::cout << typeid(T).name() << " does not have Dump\n"; 
} 

template <typename T> 
void dump(T& t) { dump(t, has_dump<T>()); } 

Une autre utilisation des traits de type serait conjointement avec les enable_if installations:

template <typename T> 
typename boost::enable_if< has_dump<T> >::type dump(T& t) 
{ 
    t.Dump(); 
} 

// disable_if exists too... 

Ici, au lieu d'un message d'erreur d'exécution, vous pouvez obtenir une erreur de compilation si le type n'a pas has_dump activé, pas sûr si vous le souhaitez.

Cependant ces deux méthodes sont assez lourdes, puisque la détection n'est pas automatisée. C'est pourquoi il y a la bibliothèque Boost.Concept.

L'idée est que la vérification sera effectuée par un objet Concept, créé pour tester les exigences, et donc vous n'avez plus besoin de spécialiser les traits, ce qui facilite le développement. Cependant j'ai toujours trouvé que la documentation de Boost.Concept manquait un peu.

+1

Eh bien, votre alternative est aussi trop compliquée pour mon but mais j'accepterai votre réponse comme un "non" si personne ne trouve un vrai "oui" dans quelques jours. –

+0

@kaptnole: Je suis d'accord que c'est verbeux, l'ensemble des concepts était simplement ceci ... espérons qu'ils vont le faire en C++ 1x –

+0

Pourriez-vous donner plus d'informations sur l'instruction suivante: "Et puis vous vider-activer vos types en spécialisant la structure has_dump? "Je pense que vous faites référence à quelque chose comme" template <> struct has_dump : boost :: mpl :: true_ {}; "comme discuté dans l'article trouvé à http: // fr .cppreference.com/w/cpp/language/template_specialization mais je ne suis pas certain –