2012-07-03 7 views
9

En una función de plantilla que tiene este aspecto:Making sin firmar en C++ 11

template<typename T> constexpr T foo(T a, T b) { return /*recursive call*/; } 

estoy recibiendo una advertencia acerca de la comparación firmó vs sin firmar (debido a la comparación contra sizeof), que me había Me gusta eliminar

Conceptualmente, se necesitaría algo como esto:

template<typename T> constexpr T foo(T a, unsigned T b) { ... } 
    or 
template<typename T> constexpr T foo(T a, std::make_unsigned<T>::type b) { ... } 

Desgraciadamente, la primera versión no es C válida ++, y la segunda versión rompe la acumulación debido T no es un tipo cualificado cuando el compilador ve make_unsigned.

¿Hay una solución para esto que realmente funcione?

(NB: De alguna manera relacionada con/casi igual que Get the signed/unsigned variant of an integer template parameter without explicit traits, aunque la función en lugar de la clase (por lo que no typedefs), los rasgos o cualquier característica de C++ 11 bienvenidos explícitamente, y la solución de trabajo (es decir nomake_unsigned<T>) prefiere .)

Respuesta

10

se le olvidó un 'nombre de tipo'

template<typename T> 
constexpr T foo(T a, typename std::make_unsigned<T>::type b) { ... } 

En C++ 14 debe ser capaz de escribir

template<typename T> 
constexpr T foo(T a, std::make_unsigned_t<T> b) { ... } 

O puede implementarlo usted mismo en C++ 11:

template<typename T> 
using make_unsigned_t = typename std::make_unsigned<T>::type; 
+0

Indeed! Muchas gracias :) – Damon

+0

Estoy enfrentando un problema similar para C++ 03. Quiero dos plantillas: una para 'plantilla ' y clase 'plantilla '. Necesito probar si se puede hacer un lanzamiento de 'T' a' U'. ¿Hay alguna solución en el mundo C++ 03? (¿Esto justifica una nueva pregunta)? – jww

+1

@jww Sí, diría que debería ser su propia pregunta. – bames53