Moala
42 como int sin firmar está bien definido como “42U”.
unsigned int foo = 42U; // yeah!
¿Cómo puedo escribir “23” para que quede claro que es un int corto sin signo?
unsigned short bar = 23; // booh! not clear!
EDITAR para que el significado de la pregunta sea más claro:
template <class T>
void doSomething(T) {
std::cout << "unknown type" << std::endl;
}
template<>
void doSomething(unsigned int) {
std::cout << "unsigned int" << std::endl;
}
template<>
void doSomething(unsigned short) {
std::cout << "unsigned short" << std::endl;
}
int main(int argc, char* argv[])
{
doSomething(42U);
doSomething((unsigned short)23); // no other option than a cast?
return EXIT_SUCCESS;
}
steve jesop
no puedes Los literales numéricos no pueden tener short
o unsigned short
escribe.
Por supuesto, para asignar a bar
el valor del literal se convierte implícitamente a unsigned short
. En su primer código de muestra, usted pudo haga que la conversión sea explícita con un reparto, pero creo que ya es bastante obvio qué conversión tendrá lugar. La conversión es potencialmente peor, ya que con algunos compiladores eliminará cualquier advertencia que se emita si el valor literal está fuera del rango de un unsigned short
. Por otra parte, si usted desear usar tal valor por una buena razón, entonces es bueno sofocar las advertencias.
En el ejemplo de su edición, donde se trata de una función de plantilla en lugar de una función sobrecargada, tiene una alternativa a una conversión: do_something<unsigned short>(23)
. Con una función sobrecargada, aún podría evitar un lanzamiento con:
void (*f)(unsigned short) = &do_something;
f(23);
… pero no lo aconsejo. Si nada más, esto solo funciona si el unsigned short
versión realmente existe, mientras que una llamada con el elenco realiza la resolución de sobrecarga habitual para encontrar la versión más compatible disponible.
antoniolambert
unsigned short bar = (unsigned short) 23;
o en nuevo hablar….
unsigned short bar = static_cast<unsigned short>(23);
-
En C, esto sería lo correcto, pero los moldes de estilo C de IIRC están mal vistos en C++.
– estrella azul
25 de agosto de 2009 a las 19:32
-
¡mal visto! ¡tal vez lo he modificado con una versión actualizada para mantenerlo feliz!
– AnthonyLambert
26 de agosto de 2009 a las 9:24
al menos en Visual Studio (al menos 2013 y más reciente) puede escribir
23ui16
para obtener una constante de tipo unsigned short.
ver definiciones de macros INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, etc. en stdint.h
No sé en este momento si esto es parte del estándar C/C++
-
Esa es una extensión de Visual Studio. No es parte del estándar C. Puede implementarlo usted mismo en el estándar C++ 11 con el literales de usuario característica, como se señala en stackoverflow.com/questions/33659846/…
– usuario7610
19 de marzo a las 19:30
No hay modificadores para corto sin firmar. enteros, que tiene int
type por defecto, normalmente convertido implícitamente al tipo de destino sin problemas. Pero si realmente desea indicar explícitamente el tipo, puede escribir lo siguiente:
unsigned short bar = static_cast<unsigned short>(23);
Como puedo ver, la única razón es usar dicha indicación para deducir correctamente el tipo de plantilla:
func( static_cast<unsigned short>(23) );
Pero para tal caso más claro sería una llamada como la siguiente:
func<unsigned short>( 23 );
Hay múltiples respuestas aquí, ninguna de las cuales es terriblemente satisfactoria. Así que aquí hay una respuesta de compilación con información adicional para ayudar a explicar las cosas un poco más a fondo.
En primer lugar, evite los cortos como se sugiere, pero si los necesita, como cuando trabaja con datos de malla indexados y simplemente cambiar a cortos para su tamaño de índice reduce el tamaño de sus datos de índice a la mitad… entonces siga leyendo…
1 Si bien es técnicamente cierto que no hay manera de expresar un literal corto sin firmar en c o C++, puede eludir fácilmente esta limitación simplemente marcando su literal como sin firmar con una ‘u’.
unsigned short myushort = 16u;
Esto funciona porque le dice al compilador que 16 es int sin firmar, luego el compilador busca una manera de convertirlo en corto sin firmar, encuentra uno, la mayoría de los compiladores luego verifican el desbordamiento y hacen la conversión sin quejas. El error/advertencia de “conversión estrecha” cuando se omite la “u” es que el compilador se queja de que el código está descartando el signo. De modo que si el literal es negativo, como -1, el resultado no está definido. Por lo general, esto significa que obtendrá un valor sin firmar muy grande que luego se truncará para ajustarse al corto.
2 Hay múltiples sugerencias sobre cómo eludir esta limitación, la mayoría de los programadores experimentados las resumirán con un “no hagas eso”.
unsigned short myshort = (unsigned short)16;
unsigned short myothershort = static_cast<unsigned short>(16);
Si bien ambos funcionan, no son deseables por 2 razones principales. Primero, son prolijos, los programadores se vuelven perezosos y escribir todo eso solo para un literal es fácil de omitir, lo que conduce a errores básicos que podrían haberse evitado con una mejor solución. En segundo lugar, no son gratuitos, static_cast en particular genera un pequeño código ensamblador para realizar la conversión, y aunque un optimizador puede (o no) darse cuenta de que puede realizar la conversión, es mejor escribir código de buena calidad desde el principio.
unsigned short myshort = 16ui16;
Esta solución no es deseable porque limita quién puede leer su código y entenderlo, también significa que está comenzando a descender por la pendiente resbaladiza del código específico del compilador que puede llevar a que su código de repente no funcione debido a los caprichos de algún escritor del compilador, o alguna compañía que al azar decide “hacer un giro a la derecha”, o se va y te deja en la estacada.
unsigned short bar = L'\x17';
Esto es tan ilegible que nadie lo ha votado. Y lo ilegible debe evitarse por muchas buenas razones.
unsigned short bar = 0xf;
Esto es ilegible. Si bien ser capaz de leer, comprender y convertir hexadecimal es algo que los programadores serios realmente necesitan aprender, es muy ilegible rápido qué número es este: 0xbad; Ahora conviértalo a binario… ahora octal.
3 Por último, si encuentra que todas las soluciones anteriores no son deseables, ofrezco otra solución que está disponible a través de un operador definido por el usuario.
constexpr unsigned short operator ""_ushort(unsigned long long x)
{
return (unsigned short)x;
}
y para usarlo
unsigned short x = 16_ushort;
Es cierto que esto tampoco es perfecto. Primero, toma un largo largo sin firmar y lo reduce hasta un corto sin firmar que suprime las posibles advertencias del compilador en el camino, y usa el estilo c. Pero es constexpr lo que garantiza que es gratis en un programa optimizado, pero que se puede implementar durante la depuración. También es corto y agradable, por lo que es más probable que los programadores lo usen, y es expresivo, por lo que es fácil de leer y comprender. Desafortunadamente, requiere un compilador reciente, ya que lo que se puede hacer legalmente con los operadores definidos por el usuario ha cambiado en las distintas versiones de C++.
Así que elija su intercambio, pero tenga cuidado, ya que puede arrepentirse más tarde. Programación feliz.
Tyler McHenry
Desafortunadamente, el único método definido para esto es
Uno o dos caracteres entre comillas simples (‘), precedidos por la letra L
De acuerdo a http://cpp.comsci.us/etymology/literals.html
Lo que significa que tendría que representar su número como una secuencia de escape ASCII:
unsigned short bar = L'\x17';
micrófono
Desafortunadamente, no pueden. Pero si las personas solo miran dos palabras detrás del número, deberían ver claramente que es corto… No es TAN ambiguo. Pero sería lindo.
-
Es ambiguo si un método se comporta de manera diferente para un int sin firmar y un short sin firmar y si lo pasa como doThings(42U);. ¿Algún otro modo que no sea doThings((unsigned short)23) ?
– Moala
25 de agosto de 2009 a las 16:12
Declare un objeto ‘const unsigned short’ con un nombre apropiado y luego utilícelo en lugar del 23. Todavía no lo ayuda a indicar explícitamente que 23 está destinado a ser unsigned short, pero al menos solo necesita verificar esa declaración para asegurar la corrección. En todas partes se usará la constante y así el significado será claro.
-Richard Corden
25 de agosto de 2009 a las 16:10
@Richard Corden: se usa cientos de veces como valores de entrada y resultados en pruebas unitarias, por lo que cuanto más corto, mejor … U para int sin firmar es conveniente, pero los moldes (cortos sin firmar) o los objetos cortos sin firmar const son exasperantes.
– Moala
25 de agosto de 2009 a las 21:27
Está preguntando cómo declarar un literal corto sin firmar. Si hubieras buscado esa pregunta, habrías encontrado tu respuesta. Como se ha dicho, no se puede.
– código_deft
26 de agosto de 2009 a las 2:39