2009-08-25 2 views
35

42 als unsigned int ist gut als "42U" definiert.Wie schreibe ich ein vorzeichenloses kurzes int-Literal?

unsigned int foo = 42U; // yeah! 

Wie kann ich schreibe "23", so dass es klar ist, es ein unsigned short int ist?

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

EDIT so, dass die Bedeutung der Frage mehr klar:

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

ist Declare a ' const unsigned short 'Objekt mit einem passenden Namen und dann verwenden Sie das anstelle der 23. Es hilft Ihnen immer noch nicht explizit sagen, dass 23 soll nicht signiert kurz sein, aber zumindest müssen Sie nur diese Erklärung zu überprüfen, um die Richtigkeit zu gewährleisten . Überall sonst wird die Konstante verwendet und so wird die Bedeutung klar sein. –

+0

@Richard Corden: Es ist hunderte Male als Eingabewerte und führt in Unit-Tests, also je kürzer, desto besser ... U für unsigned int ist bequem, aber (unsigned short) Casts oder Const unsigned kurze Objekte sind ärgerlich . – moala

+0

Sie fragen, wie Sie ein unsigniertes Kurzliteral deklarieren. Wenn Sie nach dieser Frage gesucht hätten, hätten Sie Ihre Antwort gefunden. Wie gesagt wurde, kannst du nicht. –

Antwort

32

Sie können nicht. Numerische Literale können keinen short oder unsigned short Typ haben.

Um den Wert bar zuzuweisen, wird der Wert des Literals implizit in unsigned short konvertiert. In Ihrem ersten Beispielcode können Sie diese Konvertierung explizit mit einer Besetzung machen, aber ich denke, es ist ziemlich offensichtlich, welche Konvertierung bereits stattfinden wird. Casting ist potenziell schlimmer, da es bei einigen Compilern alle Warnungen unterdrückt, die ausgegeben würden, wenn der Literalwert außerhalb des Bereichs von unsigned short liegt. Wenn Sie jedoch wollen einen solchen Wert aus einem guten Grund zu verwenden, dann ist die Unterdrückung der Warnungen gut.

In dem Beispiel in Ihrer Bearbeitung, in dem es sich eher um eine Vorlagenfunktion als um eine überladene Funktion handelt, haben Sie eine Alternative zu einem Cast: do_something<unsigned short>(23). Mit einer überladenen Funktion könnten Sie immer noch einen Cast vermeiden mit:

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

... aber ich rate davon ab. Wenn nichts anderes, funktioniert das nur, wenn die unsigned short Version tatsächlich existiert, während ein Aufruf mit dem Cast die übliche Überladungsauflösung durchführt, um die kompatibelste verfügbare Version zu finden.

0

Leider ist die einzige Methode für diese definiert ist

Ein oder zwei Zeichen in einfachen Anführungszeichen ('), durch den L Brief voran

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

Welche bedeutet, dass Sie Ihre Nummer als ASCII-Escape-Sequenz darstellen müssten:

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

Ihr Literal wird den Typ 'wchar_t' haben. Die von Ihnen angegebene Quelle ist falsch. – avakar

+0

Danke für die Korrektur. Ich lasse diese Antwort für den Fall, dass jemand anderen durch diesen Link irregeführt wird (was auf eine offensichtliche Google-Suche für diese Frage kommt), wie ich war. –

+1

Es hat mehr Probleme, wie ASCII angenommen wird. 'A' ist nicht immer 65. – MSalters

0

Leider können sie nicht. Aber wenn die Leute nur zwei Wörter hinter der Nummer sehen, sollten sie deutlich sehen, dass es ein kurzer ... Es ist nicht so zweideutig. Aber es wäre nett.

+0

Es ist mehrdeutig, wenn eine Methode sich für unsigned int und unsigned short anders verhält und wenn Sie es als doThings (42U); übergeben. Jeder andere Weg als doThings ((unsigned short) 23)? – moala

0

Wenn Sie die Menge als 4-stellige Hexadezimalzahl ausdrücken, ist die Unsigned-Kürzel möglicherweise deutlicher.

unsigned short bar = 0x0017;

+2

0x0017 als unsigned short kann für den Leser klar sein, aber nicht für den Compiler. – moala

8
unsigned short bar = (unsigned short) 23; 

oder in neuen sprechen ....

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

In C wäre dies das Richtige, aber IIRC C-Style Casts sind in C++ verpönt. – starblue

+3

verpönt! Vielleicht habe ich es mit einer aktuellen Version geändert, um Sie glücklich zu machen! – AnthonyLambert

1

Es gibt keine Modifikatoren für unsigned short.Ganzzahlen, die standardmäßig den Typ int haben, werden normalerweise implizit ohne Probleme in den Zieltyp konvertiert. Aber wenn Sie wirklich explizit wollen Typ angeben, könnten Sie schreiben folgendes:

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

Wie kann ich der einzige Grund sehen, ist eine solche Angabe für die richtige Aufzucht Vorlagentyp zu verwenden:

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

Aber für einem solchen Fall mehr klar, wie die folgende wäre nennen:

func<unsigned short>(23); 
0

Sie wahrscheinlich nicht zu kurz verwenden sollten, wenn Sie eine ganze Menge von ihnen haben. Es ist beabsichtigt, weniger Speicher als ein Int zu verwenden, aber dieser Int wird die "natürliche Größe" für die Architektur haben. Logisch folgt, dass ein Kurzschluss wahrscheinlich nicht. Ähnlich wie bei Bitfeldern bedeutet dies, dass Kurzschlüsse als ein Kompromiss zwischen Raum und Zeit betrachtet werden können. Das lohnt sich normalerweise nur, wenn es viel Platz kostet. Es ist unwahrscheinlich, dass Sie sehr viele Literale in Ihrer Anwendung haben, daher war es nicht notwendig, kurze Literale zu verwenden. Die Usecases überschnitten sich einfach nicht.

2

zumindest in Visual Studio (mindestens 2013 und neuer) können Sie

23ui16 

schreiben für eine Konstante vom Typ unsigned short bekommen.

siehe Definitionen von INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX usw. Makros in stdint.h

weiß ich im Moment nicht, ob dieser Teil der Standard-C/C++