2010-07-29 8 views
7

Tengo una plantilla que me gustaría compilar condicionalmente según el tipo de argumento. Solo me importa diferenciar entre "datos antiguos simples" (POD), es decir, enteros, etc. o clases/estructuras. Estoy usando C++ VS2008 en Windows.Compilación condicional usando caracteres de tipo Boost

template<T> 
class foo 
{ 
    void bar(T do_something){ 
    #if IS_POD<T> 
     do something for simple types 
    #else 
     do something for classes/structs 
    #endif 
}} 

He estado buscando en la biblioteca de impulso y puedo ver que parecen tener lo que quiero. Sin embargo, no entiendo cuál sería la sintaxis correcta para la declaración #if.

Cualquier ayuda sería apreciada.


Editar --- Después de leer las respuestas, veo que pasé por alto algo en mi definición de la cuestión. La clase foo es una clase con plantilla que solo necesita instanciar la versión de bar que es correcta para class type T. Estaba buscando una solución que pueda resolverse en tiempo de compilación. Espero que esto aclare mi problema.

Respuesta

7

Puede hacerlo sin enable_if, porque todo lo que necesita es enviar en función de características de tipo. enable_if se usa para agregar/eliminar instancias de plantilla a/desde la resolución de sobrecarga. Es posible que desee utilizar rasgos de llamada para elegir el mejor método para pasar objetos a su función. Como regla, los objetos se deben pasar por referencia, mientras que POD se pasa por valor. call_traits le permite elegir entre const y non-const referencias. El siguiente código usa const de referencia.

#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

El uso del preprocesador aquí no es posible. Eche un vistazo a Boost Enable If library en su lugar.

En concreto, en su caso, que se vería así (no probado):

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

Este será un error de compilación, una vez que la plantilla de clase se instancia, 't' es fijo, y en ese momento cuando se trate de llamar' bar' sean verá las dos definiciones y se producirá un error al compilar uno de ellos. Tenga en cuenta que esto no es SFINAE, ya que no será una falla de sustitución, el tipo se soluciona antes de la instanciación del miembro (o eso creo, nunca estoy seguro con estas cosas :)). –

3

Usted no puede resolver esto con el preprocesador, ya que no sabe nada de C++. (Es una herramienta de reemplazo de texto tonta.) Use plantillas para hacer esto.

Suponiendo IsPod<T>::result vuelve algo por el 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()); 
    } 
} 
Cuestiones relacionadas