2009-11-10 23 views
15

¿cómo puedo obtener el tipo de elementos que están contenidos en un contenedor STL?verificar el tipo de elemento en el contenedor stl - C++

+1

¿Qué intenta hacer exactamente aquí? Como C++ está tipado estáticamente, generalmente debe saber de qué tipo son los elementos (vector , por ejemplo, contiene enteros). Si explica por qué no sabe cuáles son los tipos y para qué los quiere usar, eso ayudaría a responder la pregunta. –

+0

@David Thornley: 'template void foo (std :: template arg) {/ * Aquí, no sabemos qué tipo de elementos es * /}' Creo que es una situación bastante común. – jalf

+0

@Jalf: En ese punto cierto. Pero en ese momento, foo() es solo un concepto. Pero tan pronto como uses foo() también sabrás el tipo. –

Respuesta

14

Para los envases en general, será X::value_type. Para contenedores asociativos será X::mapped_type (X::value_type corresponde a pair<const Key,T>). Está de acuerdo con el Capítulo 23 de C++ Standard.

Para comprobar que los tipos son iguales, puede usar boost::is_same.

20
container::value_type 
+0

bien eso ya es genial, pero no puedo comparar dos tipos de valores devueltos por container :: value_type. ¿alguna sugerencia? –

+2

@Patrick: no puede comparar los "valores devueltos por value_type" porque value_type es un tipo, no un valor. La comparación de dos value_types es, por lo tanto, una operación estática, no una de tiempo de ejecución. Dependiendo de lo que esté tratando de lograr, es posible que desee ver "is_same" en Boost.TypeTraits: http://www.boost.org/doc/libs/1_40_0/libs/type_traits/doc/html/boost_typetraits/reference /is_same.html –

+2

@Patrick: solicitó el * tipo * de elementos almacenados en el vector, no el * valor * de los elementos. Puede comparar los valores, no puede comparar tipos (al menos no sin muchos trucos de metaprogramación); quizás deba explicar qué es lo que está tratando de hacer. – jalf

0

¿En qué sentido? ¿Quizás usando RTTI y typeid()?

Probablemente usted tiene que utilizar contenedores :: valuetype donde envase es el nombre de su contenedor (por ejemplo, std :: vector)

Alek

0

Necesita darnos más contexto. Si quiere decir que quiere el valor conocido en tiempo de compilación para que sea fácil cambiarlo, use container::value_type.

typedef vector<int> coordinates; 

coordinates seq; 
fib::value_type elem = seq.back(); // it's easy to change int type 

Si lo que quiere decir es que el contenedor puede contener varios tipos de hormigón (derivados) y desea saber en tiempo de ejecución a continuación, probablemente debería reevaluar su enfoque. En la programación orientada a objetos, ocultar el tipo en tiempo de ejecución a veces es un enfoque poderoso, porque significa que usted hace menos suposiciones sobre con qué está trabajando. Por supuesto, puede usar RTTI, pero probablemente haya una mejor manera: necesitaríamos más contexto para contar.

Si desea comparar tipos, probablemente esté dirigiendo el camino de tiempo de ejecución. C++ es compatible con el polimorfismo, que es esencialmente esa comparación de tipo que está buscando, pero integrada en el lenguaje. ¿Desea ejecutar un conjunto diferente de instrucciones según el tipo? El polimorfismo le permite ejecutar una función diferente según el tipo de objeto. No necesita escribir una sola línea de código adicional, solo derivar de una base común.

0

usar algo como esto:

if (typeid(yourVariable)==typeid(YourClass)) //... 

Alek

+0

o dynamic_cast <> si desea probar la cadena de herencia;) –

+0

pero solo si su tipo tiene métodos virtuales. –

+0

dynamic_cast se utiliza en punteros polimórficos, por supuesto. No lo mencioné Tienes razón. Gracias por señalarlo;) –

3

Comprobar si dos tipos son la misma se pueden lograr así (sin RTTI, el valor se puede utilizar en tiempo de compilación):

template <class T, class U> 
struct same_type 
{ 
    static const bool value = false; 
}; 

//specialization for types that are the same 
template <class T> 
struct same_type<T, T> 
{ 
    static const bool value = true; 
}; 

//sample usage: 
template <class FirstContainer, class SecondContainer> 
bool containers_of_same_type(const FirstContainer&, const SecondContainer&) 
{ 
    return same_type< 
     typename FirstContainer::value_type, 
     typename SecondContainer::value_type 
    >::value; 
} 

#include <vector> 
#include <list> 
#include <iostream> 

int main() 
{ 
    std::cout << containers_of_same_type(std::vector<int>(), std::list<int>()); 
    std::cout << containers_of_same_type(std::vector<char>(), std::list<int>()); 
} 

(Esto es básicamente cómo funciona boost::is_same, menos las soluciones provisionales para ciertos compiladores).

+0

wow, eso es muy inteligente –

Cuestiones relacionadas