2011-04-21 13 views
6

Me pregunto si hay alguna manera de restringir la generación de código para una plantilla usando condiciones personalizadas. En mi caso, quiero funcionar foo para llamar solo si la clase de plantilla T se ha heredado por clase (algo así)restricción de clase de plantilla

template <class T:public bar> void foo() 
{ 
    // do something 
} 
+3

Usted podría ser capaz de usar Boost 'enable_if'. –

+0

Si se trata de herencia pública, entonces hay una forma más. Ver mi respuesta – iammilind

Respuesta

9

puede restringir T aunque el uso de "fracaso sustitución no es un error" (SFINAE):

template <typename T> 
typename std::enable_if<std::is_base_of<bar, T>::value>::type foo() 
{ 

} 

Si T no se deriva de bar, la especialización de la plantilla de función fallará y no será considerado durante la resolución de sobrecarga. std::enable_if y std::is_base_of son nuevos componentes de la biblioteca estándar de C++ agregados en la próxima revisión, C++ 0x. Si su compilación/implementación de la Biblioteca estándar aún no los admite, también puede encontrarlos en C++ TR1 o Boost.TypeTraits.

+0

De hecho, o si su biblioteca 'std' no tiene' is_base_of', está en Boost. –

+0

Sí. El equivalente de Boost sería 'boost :: enable_if > :: type'; el 'std :: enable_if' toma un' bool' como su primer argumento mientras que 'boost :: enable_if' toma un tipo. 'std :: enable_if' es equivalente a' boost :: enable_if_c'. –

+0

¿tiene alguna idea de cómo se implementa la biblioteca std en sí misma enable_if o is_base_of classes? – Ali1S232

0

Sí, se puede utilizar la siguiente técnica (para herencia pública). Causará una sobrecarga de solo una inicialización de puntero.

Editar: Reescribiendo

template<typename Parent, typename Child> 
struct IsParentChild 
{ 
    static Parent* Check (Child *p) { return p; } 
    Parent* (*t_)(Child*); 
    IsParentChild() : t_(&Check) {} // function instantiation only 
}; 

template<typename T> 
void foo() 
{ 
    IsParentChild<Bar, T> check; 
// ... 
} 
Cuestiones relacionadas