2009-08-25 14 views
35

42 como unsigned int está bien definido como "42U".Cómo escribir un literal int corto sin signo?

unsigned int foo = 42U; // yeah! 

¿Cómo puedo escribir "23", por lo que está claro es un entero corto sin signo?

unsigned short bar = 23; // booh! not clear! 

edición para que el significado de la cuestión es 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; 
} 
+2

declarar un ' const unsigned short 'object con un nombre apropiado y luego usar eso en lugar del 23. Todavía no ayuda a afirmar explícitamente que 23 está destinado a ser sin signo corto, pero al menos solo necesita verificar esa declaración para asegurar la corrección . En cualquier otro lugar usará la constante, por lo que el significado será claro. –

+0

@Richard Corden: se usa cientos de veces como valores de entrada y da como resultado pruebas unitarias, por lo tanto cuanto más corto, mejor ... U para unsigned int es conveniente, pero los cortos (unsigned short) o const short object son exasperantes . – moala

+0

Está preguntando cómo declarar un literal corto sin firmar. Si buscara esa pregunta, habría encontrado su respuesta. Como se ha dicho, no puedes. –

Respuesta

32

No se puede. Los literales numéricos no pueden tener el tipo short o unsigned short. Por supuesto, para asignar a bar, el valor del literal se convierte implícitamente en unsigned short. En su primer código de ejemplo, podría hacer explícita esa conversión con un molde, pero creo que ya es bastante obvio qué conversión tendrá lugar. El lanzamiento es potencialmente peor, ya que con algunos compiladores retendrá las advertencias que se emitirían si el valor literal está fuera del rango de unsigned short. Por otra parte, si quiere para usar dicho valor por una buena razón, entonces reprimir las advertencias es bueno.

En el ejemplo en su edición, donde resulta ser una función de plantilla en lugar de una función sobrecargada, tiene una alternativa a un molde: do_something<unsigned short>(23). Con una función sobrecargada, aún puede evitar un reparto con:

void (*f)(unsigned short) = &do_something; 
f(23); 

... pero no lo aconsejo. Si nada más, esto solo funciona si realmente existe la versión unsigned short, mientras que una llamada con el reparto realiza la resolución de sobrecarga habitual para encontrar la versión más compatible disponible.

0

Por desgracia, el único método definido para esto es

uno o dos caracteres de comillas simples ('), precedido por la letra L

Según http://cpp.comsci.us/etymology/literals.html

Qué significa que debe representar su número como una secuencia de escape ASCII:

unsigned short bar = L'\x17'; 
+5

Tu literal tendrá el tipo 'wchar_t'. La fuente que citas es incorrecta. – avakar

+0

Gracias por la corrección. Voy a dejar esta respuesta en caso de que alguien más se deje engañar por ese enlace (que aparece en una búsqueda obvia de Google para esta pregunta), como lo era yo. –

+1

Tiene más problemas, como suponer ASCII. 'A' no siempre es 65. – MSalters

0

Desafortunadamente, no pueden. Pero si la gente solo mira dos palabras detrás del número, deberían ver claramente que es corto ... No es TAN ambiguo. Pero sería lindo.

+0

Es ambiguo si un método se comporta de manera diferente para unsigned int y unsigned short y si lo pasa como doThings (42U) ;. Cualquier forma que no sea hacer cosas ((corto sin firmar) 23)? – moala

0

Si expresa la cantidad como un número hexadecimal de 4 dígitos, la falta de signo puede ser más clara.

unsigned short bar = 0x0017;

+2

0x0017 como un corto sin firmar puede ser claro para el lector, pero no para el compilador. – moala

8
unsigned short bar = (unsigned short) 23; 

o en la nueva hablar ....

unsigned short bar = static_cast<unsigned short>(23); 
+2

En C esto sería lo correcto, pero los moldes de estilo IIRC C están mal vistos en C++. – starblue

+3

mal visto! ¡tal vez lo he modificado con una versión actualizada para mantenerte feliz! – AnthonyLambert

1

No hay modificadores para unsigned short.Enteros, que tiene el tipo int de forma predeterminada, por lo general se convierte implícitamente al tipo de destino sin problemas. Pero si realmente desea expresamente indique el tipo, podría escribir lo siguiente:

unsigned short bar = static_cast<unsigned short>(23); 

Como puedo ver la única razón es el uso de tal indicación para el correcto tipo de plantilla de la deducción:

func(static_cast<unsigned short>(23)); 

Pero para tal caso más claro sería llamada como la siguiente:

func<unsigned short>(23); 
0

probablemente no debería usar una palabra, a menos que tenga una gran cantidad de ellos. Está pensado para usar menos almacenamiento que un int, pero ese int tendrá el "tamaño natural" para la arquitectura. Lógicamente se deduce que un corto probablemente no. Al igual que en los campos de bit, esto significa que los pantalones cortos se pueden considerar una compensación de espacio/tiempo. Por lo general, solo vale la pena si te compra un montón de espacio. Sin embargo, es poco probable que tenga muchos literales en la aplicación, por lo que no era necesario contar con literales cortos. Los casos de uso simplemente no se superponen.

2

al menos en Visual Studio (al menos 2013 y posteriores) se puede escribir

23ui16 

para obtener una constante de tipo sin signo corto.

ver las definiciones de INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, etc. macros en stdint.h

no sé en este momento si esto es parte del estándar de C/C++

Cuestiones relacionadas