2009-08-25 16 views
35

42 come int unsigned è ben definito come "42U".Come scrivere un letterale int breve senza segno?

unsigned int foo = 42U; // yeah! 

Come posso scrivere "23" in modo che sia chiaro che è un corto unsigned int?

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

EDIT in modo che il senso della domanda è più chiaro:

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

dichiarare un ' const unsigned short 'object con un nome appropriato e quindi usa quello al posto del 23. Non ti aiuta ancora a dichiarare esplicitamente che 23 è inteso per essere unsigned short, ma almeno devi solo controllare quella dichiarazione per assicurarti la correttezza . Ovunque altrimenti userà la costante e quindi il significato sarà chiaro. –

+0

@Richard Corden: è utilizzabile centinaia di volte come valori di input e risulta nei test unitari, quindi più breve è, meglio è ... U per unsigned int è conveniente, ma i cast (unsigned short) o const short non firmati sono esasperanti . – moala

+0

Stai chiedendo come dichiarare un letterale corto senza segno. Se avessi cercato quella domanda avresti trovato la tua risposta. Come è stato detto non puoi. –

risposta

32

Non è possibile. I valori letterali numerici non possono avere il tipo short o unsigned short.

Naturalmente per assegnare a bar, il valore del valore letterale viene convertito implicitamente in unsigned short. Nel tuo primo codice di esempio, puoi rendere questa conversione esplicita con un cast, ma penso che sia abbastanza ovvio già che la conversione avrà luogo. La trasmissione è potenzialmente peggiore, poiché con alcuni compilatori annullerà qualsiasi avviso che verrebbe emesso se il valore letterale non rientra nell'intervallo di unsigned short. Quindi, di nuovo, se si si desidera che utilizzi tale valore per una buona ragione, quindi la risoluzione degli avvisi è buona.

Nell'esempio della modifica, dove capita di essere una funzione modello piuttosto che una funzione sovraccaricata, si dispone di un'alternativa a un cast: do_something<unsigned short>(23). Con una funzione di sovraccarico, si potrebbe ancora evitare un cast con:

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

... ma io non consigliarlo. Se non altro, funziona solo se la versione unsigned short esiste effettivamente, mentre una chiamata con il cast esegue la solita risoluzione di sovraccarico per trovare la versione più compatibile disponibile.

0

Purtroppo, l'unico metodo definito per questo è

uno o due caratteri in apici ('), preceduto dalla lettera L

Secondo http://cpp.comsci.us/etymology/literals.html

Quale significa che devi rappresentare il tuo numero come sequenza di escape ASCII:

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

Il tuo letterale avrà tipo 'wchar_t'. La fonte che citi è sbagliata. – avakar

+0

Grazie per la correzione. Lascerò questa risposta nel caso in cui qualcun altro venga fuorviato da quel link (che compare su una ovvia ricerca su google per questa domanda), come lo ero io. –

+1

Ha più problemi, come l'assunzione di ASCII. 'A' non è sempre 65. – MSalters

0

Purtroppo, non possono. Ma se le persone guardano solo due parole dietro il numero, dovrebbero chiaramente vedere che è un breve ... Non è così ambiguo. Ma sarebbe bello.

+0

È ambiguo se un metodo si comporta in modo diverso per unsigned int e unsigned short e se lo si passa come doThings (42U) ;. Un modo diverso da doThings ((senza segno corto) 23)? – moala

0

Se si esprime la quantità come un numero esadecimale a 4 cifre, la mancanza senza segno potrebbe essere più chiara.

unsigned short bar = 0x0017;

+2

0x0017 come corto non firmato può essere chiaro per il lettore, ma non per il compilatore. – moala

8
unsigned short bar = (unsigned short) 23; 

o in nuova parlare ....

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

In C questa sarebbe la cosa giusta da fare, ma i cast in stile C IIRC sono disapprovati in C++. – starblue

+3

disapprovato! forse l'ho modificato con una versione aggiornata per farti felice! – AnthonyLambert

1

ci sono modificatori per unsigned short.Numeri interi, che ha il tipo int per impostazione predefinita, in genere convertito implicitamente in tipo di destinazione senza problemi. Ma se si vuole veramente in modo esplicito tipo indicare, si potrebbe scrivere il seguente:

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

come posso vedere l'unico motivo è quello di utilizzare tale indicazione per il corretto tipo di modello Ricavare:

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

Ma per tale caso più chiaro sarebbe chiamata come la seguente:

func<unsigned short>(23); 
0

Probabilmente non dovresti usare l'abbreviazione, a meno che tu non ne abbia un sacco. È inteso per usare meno memoria di un int, ma che int avrà la "dimensione naturale" per l'architettura. Logicamente ne consegue che un corto probabilmente no. Simile ai bitfield, questo significa che i cortometraggi possono essere considerati un compromesso spazio/tempo. Di solito ne vale la pena solo se ti compra un sacco di spazio. È improbabile che nella tua applicazione ci siano davvero molti letterali, quindi non era necessario prevedere brevi letterali. Gli accessori semplicemente non si sovrapponevano.

2

almeno in Visual Studio (almeno 2013 e successivi) si possono scrivere

23ui16 

per ottenere una costante di tipo unsigned short.

vedono definizioni di INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, ecc macro in stdint.h

non so al momento se questo è parte dello standard C/C++

Problemi correlati