mi chiedo seIs std :: is_unsigned <bool> :: valore ben definito?
std::is_unsigned<bool>::value
è ben definito secondo lo standard oppure no?
Ho posto la domanda perché typename std::make_unsigned<bool>::type
non è ben definito.
mi chiedo seIs std :: is_unsigned <bool> :: valore ben definito?
std::is_unsigned<bool>::value
è ben definito secondo lo standard oppure no?
Ho posto la domanda perché typename std::make_unsigned<bool>::type
non è ben definito.
Non esiste un concetto di firma per bool
. Da [basic.fundamental]/6:
Valori di tipo
bool
sono otrue
difalse
. [Nota: non ci sonosigned
,unsigned
,short
olong
bool
tipi o valori. - nota finale] I valori di tipobool
partecipano alle promozioni integrali (4.5).
Al contrario, signedness è esplicitamente chiamato fuori per il tipi interi firmati (paragrafo 2) e tipi unsigned interi (paragrafo 3).
Ora per i tratti is_signed
e is_unsigned
. Prima di tutto, i tratti sono sempre ben definiti, ma solo interessanti per i tipi aritmetici. bool
è un tipo aritmetico e is_signed<T>::value
è definito (vedere Tabella 49) come T(-1) < T(0)
. Utilizzando le regole della conversione booleana e delle conversioni aritmetiche standard, vediamo che questo è false
per T = bool
(perché bool(-1)
è true
, che viene convertito in 1
). Allo stesso modo, is_unsigned<T>::value
è definito come T(0) < T(-1)
, ovvero true
per T = bool
.
is_unsigned
è definito in [meta.unary.comp]/2 come
Se
is_arithmetic<T>::value
ètrue
, lo stesso risultato
bool_constant<T(0) < T(-1)>::value
; altrimenti,false
bool
† è chiaramente un tipo aritmetico (essendo solidale). Consideriamo ora [conv.bool]/1:
valore zero, il valore del puntatore nullo, o nullo valore del puntatore membro è convertito
false
; qualsiasi altro valore viene convertito intrue
.
I.e. bool(0) < bool(-1)
equivale a false < true
e quest'ultimo vale poiché i valori vengono promossi a 0
e 1
, rispettivamente.
Così is_unsigned<bool>::value
è true
(e, viceversa, è is_signed
false
), a causa del fatto che i valori bool
ean corrispondono ai valori senza segno 0
e 1
durante le operazioni aritmetiche. Tuttavia, non ha senso valutare la firma di bool
, tanto meno eseguire make_unsigned
su di esso, poiché non rappresenta numeri interi, ma piuttosto stati.
bool
in primo luogo è determinata dalla sua clausola requisito essendo inesistente,
bool
non essendo un tipo incompleto ([res.on.functions]/(2.5)) e nessun altro requisito è menzionato in [meta.rqmts] per
UnaryTypeTraits.
Sì, è ben definito e il risultato dovrebbe essere std::is_unsigned<bool>::value == true
La documentazione per std::is_signed
dice
Se
T
è un tipo aritmetico firmato, fornisce agli Stati valore costante pari vero. Per qualsiasi altro tipo, il valore è falso.
Allora, se si guarda a std::is_arithmetic
Se T è un tipo aritmetico (cioè, un tipo intero o un tipo in virgola mobile), fornisce il valore della costante membro paritario vero. Per qualsiasi altro tipo, il valore è falso.
che porta infine std::is_integral
Verifica se T è un tipo integrale. Fornisce il valore costante elemento che è uguale a true, se T è il tipo
bool
,char
,char16_t
,char32_t
,wchar_t
,short
,int
,long
,long long
o qualsiasi tipi interi estesi attuazione definiti, compresi eventuali firmata, senza segno e varianti qualificate per CV. Altrimenti, il valore è uguale a falso.
interessante notare che v'è un'altra funzione che indica std::numeric_limits::is_signed
Il valore di
std::numeric_limits<T>::is_signed
ètrue
per tutti i tipi aritmetici firmatiT
efalse
per i tipi senza segno. Questa costante è significativa per tutte le specializzazioni.
Qualora la specializzazione per bool
è elencato come false
, che conferma anche che bool
è considerato senza segno.
cppreference non è una fonte autorevole, ma solo un'interpretazione. OP aveva bisogno di un'informazione autorevole - lo standard. –
@IlyaPopov Nella maggior parte dei casi cppreference cita lo standard verbatim e indica quale versione (C++ 03/11/14/etc) si applica a. – CoryKramer
Sì, si chiama cpp _reference_ per un motivo. A differenza di cplusplus.com. – edmz
Sì, è ben definito, come qualsiasi altro tratto di tipo unario.
C++ 14 (n4140) 20.10.4/2 "di tipo tratti unari" mandati:
Ciascuno di questi modelli saranno un UnaryTypeTrait (20.10.1) con un BaseCharacteristic di
true_type
se la condizione corrispondente è vera, altrimentifalse_type
.
20.10.1/1:
Un UnaryTypeTrait descrive una struttura di tipo. Deve essere un modello di classe che accetta un argomento modello e, facoltativamente, argomenti aggiuntivi che consentono di definire la proprietà descritta. Sarà
DefaultConstructible
,CopyConstructible
, e pubblicamente e senza ambiguità derivata, direttamente o indirettamente, dalla sua BaseCharacteristic, che è una specializzazione del modellointegral_constant
(20.10.3), con gli argomenti al modellointegral_constant
determinato dal requisiti per la particolare proprietà descritta. I nomi dei membri di BaseCharacteristic non devono essere nascosti e devono essere disponibili in modo non ambiguo in UnaryTypeTrait.
Da ciò segue che il costrutto std::is_unsigned<T>::value
deve essere ben definita per ogni tipo T
, se il concetto di "signedness" senso per il tipo o meno.
Leggero nitpick: "i valori sono promossi a 0 e 1, rispettivamente" non è corretto al 100%. Le regole di conversione (4.12) dicono che un valore intero zero viene convertito in 'false' e _anche altro valore_viene convertito in' true' (nessun 1 è coinvolto ovunque). Lo standard definisce anche una conversione in intero dove 'true' convertirà _ in 1, e' false' convertirà _ in 0, tuttavia non dirà nulla di ciò che i valori in realtà sono _are_. Per quanto ne sappiamo, 'true' potrebbe essere 67 e' false' potrebbe essere 172 (questo non è quasi mai il caso, ma secondo lo standard potrebbe essere). Ancora +1. – Damon
@Damon Aspetta, non vedo come le tue osservazioni si applicano alla mia frase. Ho fatto riferimento ai valori promossi a 0 e 1 durante la promozione integrale che viene applicata durante la valutazione di 'false
Columbo
Quello che voglio dire è che 'bool (-1)' converte in 'true' subito, non c'è promozione integrale a 1 coinvolto. Qualsiasi valore diverso da zero converte immediatamente in 'true'. Quindi, 'bool (0)
Damon