2016-01-05 3 views

Antwort

62

Es gibt kein Konzept der Signedness für bool. Von [basic.fundamental]/6:

Werte vom Typ bool sind entweder true von false. [Hinweis: Es gibt keine signed, unsigned, bool Typen oder Werte. - Endnote] Werte des Typs bool nehmen an integrierten Aktionen (4.5) teil.

Im Gegensatz dazu wird Signedness ausdrücklich für den Typen Signed Integer (Absatz 2) und unsigned Integer-Typen (Absatz 3) genannt werden.

Jetzt für die is_signed und is_unsigned Merkmale. Zunächst einmal sind die Eigenschaften immer klar definiert, aber nur für arithmetische Typen interessant. bool ist ein arithmetischer Typ und is_signed<T>::value ist definiert (siehe Tabelle 49) als T(-1) < T(0). Unter Verwendung der Regeln der booleschen Konvertierung und der arithmetischen Standardkonvertierungen sehen wir, dass dies false für T = bool ist (weil bool(-1)true ist, die zu 1 konvertiert). In ähnlicher Weise ist is_unsigned<T>::value als T(0) < T(-1) definiert, was true für T = bool ist.

22

is_unsigned ist in [meta.unary.comp]/2 als

Wenn is_arithmetic<T>::valuetrue ist, das gleiche Ergebnis wie
bool_constant<T(0) < T(-1)>::value; Andernfalls false

bool ist eindeutig ein arithmetischer Typ (integral). Nun betrachten [conv.bool]/1:

Ein Nullwert, Null-Zeiger-Wert oder null Element Zeigerwert zu false umgewandelt wird; Jeder andere Wert wird in true konvertiert.

I.e. bool(0) < bool(-1) entspricht false < true, und Letzteres gilt, da die Werte auf 0 bzw. 1 hochgestuft werden.

Somit ist is_unsigned<bool>::valuetrue (und umgekehrt, ist is_signedfalse), aufgrund der Tatsache, dass bool ean Werte auf die Werte ohne Vorzeichen entsprechen und 01 während arithmetischer Operationen. Es macht jedoch keinen Sinn, bools Signedness zu bewerten, viel weniger make_unsigned darauf durchzuführen, da es keine Ganzzahlen, sondern Zustände darstellt.


: Die Tatsache, dass diese Vorlage zu bool in erster Linie durch seine Requirement Klausel ist nicht vorhanden, wird bestimmt, anwendbar ist bool keine unvollständiger Typ ist ([res.on.functions]/(2.5)) und keine weiteren Anforderungen in [meta.rqmts] für UnaryTypeTraits erwähnt werden.

+0

Leichter Nitpick: "Werte werden auf 0 bzw. 1 hochgestuft" ist nicht 100% richtig. Die Konvertierungsregeln (4.12) sagen, dass ein ganzzahliger Wert von Null in "false" konvertiert wird und dass jeder andere Wert in "true" konvertiert wird (keine 1 ist irgendwo involviert). Der Standard definiert auch eine Konvertierung zurück in den Integer, wobei "true" auf "1" konvertiert wird, und "false" wird auf "0" konvertiert, es sagt jedoch nichts darüber aus, was die Werte tatsächlich sind. Nach allem, was wir wissen, könnte "wahr" 67 sein und "falsch" könnte 172 sein (das ist fast sicher nie der Fall, aber gemäß dem Standard könnte es sein). Immer noch +1. – Damon

+2

@Damon Warten Sie, ich sehe nicht, wie Ihre Bemerkungen auf meinen Satz zutreffen. Ich habe auf die Werte hingewiesen, die während der ganzzahligen Beförderung, die während der Bewertung von "falsch Columbo

+0

Was ich meine ist, dass 'bool (-1)' sofort zu 'true' konvertiert, es gibt keine integrale Promotion zu 1 involviert. Jeder Wert ungleich Null wird sofort in 'true' umgewandelt. Somit ist 'bool (0) Damon

9

Ja es gut definiert ist und das Ergebnis sein sollte std::is_unsigned<bool>::value == true

Die Dokumentation für std::is_signed sagt

Wenn T ein signierter arithmetischer Typ ist stellt das Element konstanten Wert gleich wahr. Für jeden anderen Typ ist der Wert false.

Also dann, wenn Sie std::is_arithmetic sehen

Wenn T ist ein arithmetischer Typ (das heißt, ein integraler Typen oder ein Gleitkommatyp) stellt das Element konstanten Wert gleich wahr. Für jeden anderen Typ ist der Wert false.

die schließlich führt zu std::is_integral

Prüft, ob T ein integraler Typ ist. Stellt den konstanten Wert Element, das gleich wahr ist, wenn T der Typ bool, char, char16_t, char32_t, wchar_t, short, int, long, long long oder beliebige Implementierung definiert erweiterten Integer-Typen, einschließlich jeglicher signiert, unsigned und cv-qualifizierte Varianten. Ansonsten ist der Wert gleich falsch.

Interessanterweise gibt es eine andere Funktion std::numeric_limits::is_signed die

Der Wert std::numeric_limits<T>::is_signed Staaten ist true für alle signierten arithmetischen Typen T und false für die unsigned-Typen. Diese Konstante ist für alle Spezialisierungen sinnvoll.

Wo die Spezialisierung für bool als false aufgeführt wird, das bestätigt auch, dass bool ohne Vorzeichen betrachtet.

+0

cppreference ist keine autoritative Quelle, nur Interpretation. OP benötigte eine maßgebliche Information - den Standard. –

+2

@IlyaPopov In den meisten Fällen zitiert cppreference den Standard-Verbatim und gibt an, auf welche Version (C++ 03/11/14/etc) es zutrifft. – CoryKramer

+0

Ja, es heißt cpp _reference_ aus einem Grund. Im Gegensatz zu cplusplus.com. – edmz

10

Ja, es ist genau definiert, wie auch alle anderen unären Typen.

C++ 14 (n4140) 20.10.4/2 "Unary Typ Traits" Mandate:

Jede dieser Vorlagen wird eine UnaryTypeTrait (20.10 sein.1) mit einer BaseCharacteristic von true_type, wenn die entsprechende Bedingung zutrifft, ansonsten false_type.

20.10.1/1:

A UnaryTypeTrait beschreibt eine Eigenschaft eines Typ. Es soll eine Klassenvorlage sein, die ein Vorlagentyp Argument und optional zusätzliche Argumente, die bei der Definition der beschriebenen Eigenschaft helfen. Es soll DefaultConstructible, CopyConstructible und öffentlich und eindeutig abgeleitet ist, direkt oder indirekt, aus seinem BaseCharacteristic,, die eine Spezialisierung der Vorlage ist integral_constant (20.10.3), mit den Argumenten der Vorlage integral_constant durch die ermittelte Anforderungen für die bestimmte Eigenschaft beschrieben werden. Die Membernamen der BaseCharacteristic sollen nicht ausgeblendet sein und im UnaryTypeTrait eindeutig zur Verfügung stehen.

Daraus folgt, dass das Konstrukt std::is_unsigned<T>::value gut definierte T, ob der Begriff der „Signedness“ für jede Art Sinn für die Art macht oder nicht sein muss.

Verwandte Themen