La única manera correcta de hacer esto es un enfoque como este.
template <typename T>
bool points_within_array(T* p, T* begin, T* end)
{
for (; begin != end; ++begin)
{
if (p == begin)
return true;
}
return false;
}
Es obvio que esto no funciona si T == void
. No estoy seguro si dos void*
definen técnicamente un rango o no. Ciertamente, si usted tenía Derived[n]
, sería incorrecto decir que (Base*)Derived, (Base*)(Derived + n)
define un rango válido por lo que no puede ver que es válida para definir un rango con otra cosa que no sea un indicador al tipo de elemento de la matriz real.
El método siguiente falla porque no se especifica qué <
devuelve si los dos operandos no apuntan a miembros del mismo objeto o elementos de la misma matriz. (5,9 [expr.rel]/2)
template <typename T>
bool points_within_array(T* p, T* begin, T* end)
{
return !(p < begin) && (p < end);
}
El método a continuación falla, ya que también se especifica lo std::less<T*>::operator()
devoluciones si los dos operandos no apuntan a los miembros del mismo objeto o elementos de la misma matriz.
Es cierto que un std::less
hay que especializarse para cualquier tipo de puntero para producir un orden total si el construido en <
no, pero esto sólo es útil para usos tales como proporcionar una clave para un set
o map
. No se garantiza que el orden total no intercala matrices u objetos distintos entre sí.
Por ejemplo, en una arquitectura de memoria segmentada, el desplazamiento de objeto se podría usar para <
y como el diferenciador más significativo para std::less<T*>
con el índice de segmento utilizado para romper relaciones. En dicho sistema, un elemento de una matriz podría ordenarse entre los límites de una segunda matriz distinta.
template <typename T>
bool points_within_array(T* p, T* begin, T* end)
{
return !(std::less<T*>()(p, begin)) && (std::less<T*>()(p, end));
}
Tu comparación funciona, pero en realidad no garantiza que el 'final' tenga nada que ver con la matriz. Creo que es mejor usar una talla (ver mi respuesta a continuación). – BeeBand
@jweyrich? ¿Por qué dices eso? Suponiendo que el OP solo utiliza conversiones de puntero bien definidas, cada puntero del programa apunta a datos bien alineados (o son 'nulos'). Los datos no alineados esencialmente no existen de acuerdo con el estándar C++. 'p' garantiza que se alineará a menos que exista un comportamiento indefinido en el sitio de la llamada. – jalf
@jalf: Retracté mi comentario. Gracias por la lección. – jweyrich