2009-12-23 23 views
6

Por ejemplo:¿Cómo puedo encontrar el tamaño más grande (en tamaño) de dos enteros?

template <typename Type1, typename Type2> 
void fun(const Type1 &v1, const Type2 &v2) 
{ 
    largest<Type1, Type2>::type val = v1 + v2; 
    . 
    . 
    . 
}; 

Me gustaría saber si hay un "grande" en algún lugar, tal vez en aumento.

+0

Relacionados: http://stackoverflow.com/questions/357629/how-do-you-find-the-range-of-values-that-integer-types-can-represent-in-c –

+0

También puede utilice la plantilla 'uac_type' de esta solución: http://stackoverflow.com/questions/998571/c-template-for-safe-integer-casts/998982#998982. Pase los diferentes tipos y obtenga el tipo de resultado que el compilador elegiría. –

Respuesta

13
template<bool, typename T1, typename T2> 
struct is_cond { 
    typedef T1 type; 
}; 

template<typename T1, typename T2> 
struct is_cond<false, T1, T2> { 
    typedef T2 type; 
}; 

template<typename T1, typename T2> 
struct largest { 
    typedef typename is_cond< (sizeof(T1)>sizeof(T2)), T1, T2>::type type; 
}; 
+0

¿Cómo comparará unsigned int to int? Ambos tienen el mismo tamaño. – wheaties

+0

Especificó 'en tamaño' no dentro del rango, por lo que supongo que el mismo tamaño es la respuesta. –

+1

@Neil Butterworth: OK, OK. ¿Por qué repetir dos veces? Inserté ';' como desees. –

-1

Puede utilizar el sizeof función incorporada de c para obtener el tamaño de memoria del tipo. También puede llamarlo en una instancia de un tipo. Por ejemplo:

return (sizeof(v1) > sizeof(v2));

3

No hay una respuesta sencilla. Si el tipo más grande en su máquina es largo y los dos tipos pasados ​​son largos sin firmar y largos, ¿qué tipo esperaría que fuera val? Si no está firmado, corre el riesgo de un número negativo que no cabe en él. Si está firmado, puede desbordarse, pero aún así tener un número que encajaría en el espacio de número sin firmar.

Si estas limitaciones son aceptables, podría utilizar el enfoque de Alexey Malistov, pero el tipo resultante si Tipo1 y Tipo2 son del mismo tamaño, pero los diferentes tipos serán diferentes según el orden en que se pasen los valores.

Eche un vistazo a la función boost mpl if_, con la que puede elegir uno de dos tipos. Tendrá que idear sus propias reglas sobre cómo elegir el tipo resultante.

+0

Aunque solo está interesado en tipos específicos (firmado integral) me alegra que hayas mencionado esto. – joshperry

+0

Tienes razón. Las integrales deben estar firmadas o sin firmar. En mi caso, estoy interesado en los firmados, pero su observación es correcta. – chila

1

Esto no será muy factible. ¿Cómo se puede diferenciar entre unsigned int e int? No puede usar sizeof() porque ambos tienen el mismo "tamaño" en la memoria. Creo que tendrás que implementar tu propia especialización de plantilla para manejar esos casos, en cuyo caso sugiero que solo uses una función sobrecargada.

+0

Como pidió la más grande (en tamaño), no creo que sea un problema. –

+0

Ver http://en.wikipedia.org/wiki/Integer_(computer_science) Ver la respuesta de stephen que es más en profundidad que la mía. – wheaties

+0

Tienes razón. Las integrales deben estar firmadas o sin firmar. En mi caso, estoy interesado en los firmados, pero su observación es correcta. – chila

Cuestiones relacionadas