这是因为 + 被解释为一元加法,它将对整数或枚举类型执行整数提升,结果将具有提升的操作数的类型。
假设e 是一个整数或无作用域的枚举类型,无论如何都会应用整数提升,因为* 将通常的算术转换 应用到它的操作数上,该操作数最终在整数类型的积分促销。
来自 C++ 标准草案5.3.1[expr.unary.op]:
一元 + 运算符的操作数应具有算术、无范围枚举或指针类型,并且
结果是参数的值。对整数或枚举操作数执行整数提升。
结果的类型是提升操作数的类型。
积分促销在4.5部分中介绍[conv.prom]如果变量e是bool, char16_t, char32_t, or wchar_t以外的类型并且转换等级小于int 那么它将被1 段所覆盖:
除 bool、char16_t、char32_t 或 wchar_t 之外的整数类型的纯右值,其整数转换
rank (4.13) 小于 int 的 rank 可以转换为 int 类型的纯右值,如果 int 可以表示所有
源类型的值;否则,源纯右值可以转换为无符号类型的纯右值
诠释。
完整的案例可以看cppreference。
一元加号在某些情况下也可以用来解决歧义,一个有趣的案例来自Resolving ambiguous overload on function pointer and std::function for a lambda using +。
请注意,对于那些引用一元 - 和负值的答案,这是具有误导性的,如本例所示:
#include <iostream>
int main()
{
unsigned x1 = 1 ;
std::cout << -x1 << std::endl ;
}
导致:
4294967295
现场观看using gcc on wandbox。
有趣的是,从 Rationale for International Standard—Programming Languages—C:
C89 委员会从多个实现中采用了一元加号,以与一元减号对称。
而且我想不出一个好的案例来说明投射不足以实现相同的预期促销/转化。我上面引用的 lambda 示例,使用一元加号强制将 lambda 表达式转换为函数指针:
foo( +[](){} ); // not ambiguous (calls the function pointer overload)
可以使用显式强制转换来完成:
foo( static_cast<void (*)()>( [](){} ) );
可以说这个代码更好,因为意图是明确的。
值得注意的是Annotated C++ Reference Manual(ARM)它有以下评论:
一元加号是历史性的意外,一般来说是无用的。