std::is_unsigned<bool>::value 是否定义明确?

Is std::is_unsigned<bool>::value well defined?

我想知道

std::is_unsigned<bool>::value

是否符合标准?

我问这个问题是因为 typename std::make_unsigned<bool>::type 没有明确定义。

is_unsigned 在 [meta.unary.comp]/2 中定义为

If is_arithmetic<T>::value is true, the same result as
bool_constant<T(0) < T(-1)>::value; otherwise, false

bool 显然是算术类型(整数)。现在考虑 [conv.bool]/1:

A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.

bool(0) < bool(-1) 等同于 false < true,后者成立,因为值分别提升为 01

因此 is_unsigned<bool>::valuetrue(相反,is_signedfalse),因为 boolean 值对应于算术运算期间的无符号值 01。然而,评估 bool 的符号性并没有真正意义,更不用说对其执行 make_unsigned 了,因为它不代表整数,而是代表状态。


:这个模板首先适用于bool的事实是由它的Requirement子句non-existent决定的,bool不是不完整类型 ([res.on.functions]/(2.5)) 并且 [meta.rqmts] 中没有提及 UnaryTypeTraits.

的其他要求

是的,定义明确,结果应该是std::is_unsigned<bool>::value == true

std::is_signed 的文档说

If T is a signed arithmetic type, provides the member constant value equal true. For any other type, value is false.

那么如果你看看 std::is_arithmetic

If T is an arithmetic type (that is, an integral type or a floating-point type), provides the member constant value equal true. For any other type, value is false.

最终导致 std::is_integral

Checks whether T is an integral type. Provides the member constant value which is equal to true, if T is the type bool, char, char16_t, char32_t, wchar_t, short, int, long, long long, or any implementation-defined extended integer types, including any signed, unsigned, and cv-qualified variants. Otherwise, value is equal to false.

有趣的是,还有另一个函数std::numeric_limits::is_signed表示

The value of std::numeric_limits<T>::is_signed is true for all signed arithmetic types T and false for the unsigned types. This constant is meaningful for all specializations.

其中 bool 的特化被列为 false,这也证实了 bool 被认为是无符号的。

bool 没有符号的概念。来自 [basic.fundamental]/6:

Values of type bool are either true of false. [Note: There are no signed, unsigned, short, or long bool types or values. — end note] Values of type bool participate in integral promotions (4.5).

相比之下,有符号整数类型(第 2 段)和无符号整数类型(第 3 段)明确指出了有符号性.

现在是 is_signedis_unsigned 特征。首先,特征总是 well-defined,但只对算术类型感兴趣。 bool是算术类型,is_signed<T>::value定义(见Table49)为T(-1) < T(0)。通过使用布尔转换和标准算术转换的规则,我们看到这是 T = boolfalse(因为 bool(-1)true,它转换为 1).同样,is_unsigned<T>::value 定义为 T(0) < T(-1),对于 T = bool.

true

是的,它是 well-defined,与任何其他一元类型特征一样。

C++14 (n4140) 20.10.4/2 "Unary type traits" 要求:

Each of these templates shall be a UnaryTypeTrait (20.10.1) with a BaseCharacteristic of true_type if the corresponding condition is true, otherwise false_type.

20.10.1/1:

A UnaryTypeTrait describes a property of a type. It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the property being described. It shall be DefaultConstructible, CopyConstructible, and publicly and unambiguously derived, directly or indirectly, from its BaseCharacteristic, which is a specialization of the template integral_constant (20.10.3), with the arguments to the template integral_constant determined by the requirements for the particular property being described. The member names of the BaseCharacteristic shall not be hidden and shall be unambiguously available in the UnaryTypeTrait.

由此得出,对于任何类型 T,构造 std::is_unsigned<T>::value 必须是 well-defined,无论 "signedness" 的概念对该类型是否有意义.