Además de las otras respuestas, debe tenerse en cuenta que la prueba se puede utilizar en tiempo de ejecución, sino también en tiempo de compilación para seleccionar la aplicación correcta dependiendo de carnero el tipo es integral o no:
versión
tiempo de ejecución :
// Include either <boost/type_traits/is_integral.hpp> (if using Boost)
// or <type_traits> (if using c++1x)
// In the following, is_integral shoudl be prefixed by either boost:: or std::
template <typename T>
void algorithm(const T & t)
{
// some code
if (is_integral<T>::value)
{
// operations to perform if T is an integral type
}
else
{
// operations to perform if T is not an integral type
}
// some other code
}
Sin embargo, esta solución se puede mejorar cuando la implementación del algoritmo depende en gran medida de la prueba. En este caso, tendríamos la prueba en la parte superior de la función, luego un gran bloque then
y un gran bloque else
. Un enfoque común en este caso es sobrecargar la función y hacer que el compilador seleccione la implementación correcta utilizando SFINAE. Una manera fácil de hacer esto es utilizar boost::enable_if
:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
template <typename T>
typename boost::enable_if<boost::is_integral<T> >::type
algorithm(const T & t)
{
// implementation for integral types
}
template <typename T>
typename boost::disable_if<boost::is_integral<T> >::type
algorithm(const T & t)
{
// implementation for non integral types
}
Cuando se invoca la función algorithm
, el compilador "seleccionar" a la aplicación correcta en función de carnero el parámetro de plantilla es integral o no.
muy útil, gracias – davka
Diría que cada compilador que valga su grano eliminará la rama muerta en su primer ejemplo, es bastante simple. –
@Georg Fritzsche: esto es cierto, es por eso que no dije nada sobre un posible aumento de rendimiento. Sin embargo, creo que el enfoque de sobrecarga es más claro: las dos implementaciones pueden evolucionar por separado, y me pareció mejor discriminar entre lo que es estático (conocido/ejecutado en tiempo de compilación) y lo que es dinámico (conocido/ejecutado en tiempo de ejecución). Pero bueno, eso puede deberse a que pasé demasiado tiempo haciendo metaprogramación en los últimos meses. –