2010-07-29 5 views
7

J'ai un modèle que je voudrais compiler conditionnellement en fonction du type de l'argument. Je me soucie seulement de faire la différence entre "Plain Old Data" (POD), c.-à-d., Entiers, etc. ou classes/structures. J'utilise C++ VS2008 sur Windows. J'ai regardé la bibliothèque boost et je peux voir qu'ils semblent avoir ce que je veux. Cependant, je ne comprends pas ce que la syntaxe correcte pour l'instruction #if serait.Compilation conditionnelle utilisant des caractères de type Boost

Toute aide serait appréciée.


Modifier --- Après avoir lu les réponses, je vois que j'oublié quelque chose dans ma définition de la question. La classe foo est une classe modèle qui n'a besoin que d'une instance de la version de bar qui est correcte pour class type T. Je cherchais une solution qui peut être résolue à la compilation. J'espère que cela éclaircit mon problème.

Répondre

7

Vous pouvez le faire sans enable_if, parce que tout ce dont vous avez besoin est à être envoyé en fonction des caractéristiques de type. enable_if est utilisé pour ajouter/supprimer des instanciations de modèle à/de la résolution de surcharge. Vous pouvez utiliser les traits d'appel pour choisir la meilleure méthode pour passer des objets à votre fonction. En règle générale, les objets doivent être transmis par référence, alors que POD est passé par valeur. call_traits Vous pouvez choisir entre const et références non const. Le code ci-dessous utilise la référence const.

#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 

template <typename T> 
class foo { 
public: 
    void bar(typename boost::call_traits<T>::param_type obj) { 
     do_something(obj, boost::is_pod<T>()); 
    } 
private: 
    void do_something(T obj, const boost::true_type&) 
    { 
     // do something for POD 
    } 
    void do_something(const T& obj, const boost::false_type&) 
    { 
     // do something for classes 
    } 
}; 
0

L'utilisation du préprocesseur n'est pas possible ici. Jetez un oeil à Boost Enable If library à la place.

Plus précisément, dans votre cas, il ressemblerait (non testé):

void bar (typename enable_if <is_pod <T>, T>::type do_something) 
{ 
    // if is POD 
} 

void bar (typename disable_if <is_pod <T>, T>::type do_something) 
{ 
    // if not 
} 
+0

Ce sera une erreur de compilation, une fois que le modèle de classe est instancié, 'T' est fixé, et à ce moment-là lorsque vous essayez d'appeler' bar' il verra les deux définitions et il échouera à compiler l'un d'eux. Notez que ce n'est pas SFINAE, car ce ne sera pas un échec de substitution - le type est fixé avant l'instanciation du membre (ou du moins je pense, je ne suis jamais sûr de ces choses :)). –

3

Vous ne pouvez pas résoudre ce avec le préprocesseur, car il ne connaît pas C++. (C'est un outil de remplacement de texte stupide.) Utilisez des modèles pour le faire.

En supposant quelque chose IsPod<T>::result rendements aussi bien Boolean<true>/Boolean<false>:

template<T> 
class foo 
{ 
    void do_something(T obj, Boolean<true> /*is_pod*/) 
    { 
     // do something for simple types 
    } 
    void do_something(T obj, Boolean<false> /*is_pod*/) 
    { 
     // do something for classes/structs 
    } 

    void bar(T obj) 
    { 
     do_something(obj, IsPod<T>::result()); 
    } 
} 
Questions connexes