2011-06-30 11 views
11

Digamos que tengo alguna clase de plantilla dependiendo del tipo T. T podría ser casi cualquier cosa: int, int*, pair <int, int> o struct lol; no puede ser void, una referencia o cualquier cosa cv-calificado sin embargo. Para cierta optimización, necesito saber si puedo crear la subclase T. Por lo tanto, necesitaría algún tipo de rasgo is_subclassable, determinado como una combinación lógica de rasgos básicos o mediante algunos trucos de SFINAE.Plantillas de C++: cómo determinar si un tipo es adecuado para la subclase

En el ejemplo original, int y int* no son subclases, mientras pair <int, int> y struct lol son.

EDIT: Como se indica a continuación, las uniones tampoco son subclasificables y T también pueden ser un tipo de unión.

¿Cómo escribo el tipo de rasgo que necesito?

+2

Hmm. ¿Sería [is_class] (http://msdn.microsoft.com/en-us/library/bb982638.aspx) suficiente? No es seguro. –

Respuesta

13

Desea determinar si se trata de una clase no sindicalizada. No tengo forma de hacer eso (y el impulso tampoco ha encontrado la forma). Si puede vivir con casos de unión positivos falsos, puede usar un is_class.

template<typename> struct void_ { typedef void type; }; 

template<typename T, typename = void> 
struct is_class { static bool const value = false; }; 

template<typename T> 
struct is_class<T, typename void_<int T::*>::type> { 
    static bool const value = true; 
}; 

Boost tiene un is_union que utiliza órdenes internas específicas del compilador sin embargo, que le ayudará a aquí. is_class (que boost también proporciona) combinado con is_union resolverá su problema.

+0

Olvidé por completo el estuche de unión. Desafortunadamente no, los falsos positivos no son aceptables. Las señoritas son, ya que esta es una optimización después de todo. – doublep

+0

@doublep, a menos que esté usando C++ 0x, no creo que pueda resolverse de forma portátil. –

+0

Sí, supongo que tendré que condicionar la optimización al soporte de C++ 0x o simplemente soltarlo. – doublep

Cuestiones relacionadas