在调用std :: numeric_limits <unsigned char>成员之前加上一元“+”的目的是什么?

131

我在cppreference关于std::numeric_limits的文档中看到了这个例子

#include <limits>
#include <iostream>

int main() 
{
    std::cout << "type\tlowest()\tmin()\t\tmax()\n\n";

    std::cout << "uchar\t"
              << +std::numeric_limits<unsigned char>::lowest() << '\t' << '\t'
              << +std::numeric_limits<unsigned char>::min() << '\t' << '\t'
              << +std::numeric_limits<unsigned char>::max() << '\n';
    std::cout << "int\t"
              << std::numeric_limits<int>::lowest() << '\t'
              << std::numeric_limits<int>::min() << '\t'
              << std::numeric_limits<int>::max() << '\n';
    std::cout << "float\t"
              << std::numeric_limits<float>::lowest() << '\t'
              << std::numeric_limits<float>::min() << '\t'
              << std::numeric_limits<float>::max() << '\n';
    std::cout << "double\t"
              << std::numeric_limits<double>::lowest() << '\t'
              << std::numeric_limits<double>::min() << '\t'
              << std::numeric_limits<double>::max() << '\n';
}

我不理解"+"运算符在中的作用。

<< +std::numeric_limits<unsigned char>::lowest()

我已经测试过了,用"-"替换"+"同样可以起到作用。那么"+"运算符有什么用呢?

3
试试看。如果你去掉这个“+”符号,会得到什么? - Pete Becker
4
如果代码编写者愿意解释含义或使用显式转换,那么这个问题就不需要被提出。 - user202729
如果您将其替换为“-”,则输出将不是限制的正确值。 - phuclv
1
顺便说一下,如果你想自己在谷歌上搜索这种东西,这被称为“一元加”运算符——它是一元的,因为它只接受一个值(在这种情况下,就是它右边的那个东西),而“加”是谷歌友好的说法,表示 +。在这种情况下,你的查询可能会是“c++ 一元加”。这不是很直观,你仍然需要学习阅读你找到的文档,但在我看来,这是一个有用的技能。 - anon
4个回答

139

当以 char(有符号或无符号)作为参数传递给输出运算符<<时,它将按照字符形式写入。

这些函数返回的值的类型是 unsigned char。正如上面所述,它将以当前编码表示的字符打印出来,而不是它们的整数值。

加号运算符会通过整数提升将这些函数返回的unsigned char转换为int。这意味着整数值将被打印出来。

+std::numeric_limits<unsigned char>::lowest()这样的表达式本质上等同于static_cast<int>(std::numeric_limits<unsigned char>::lowest())


37

+用于将unsigned char转换为int+运算符是值保持的,但它会对其操作数引起整数提升的影响。这是为了确保您看到一个数字值,而不是一些(半)随机字符,当给定一个字符类型时,operator <<会打印出来。


20

仅为已有回答添加参考。来自CPP标准工作草案N4713的:

8.5.2.1 一元运算符
...

  1. 一元正操作数须是算术类型、未作用域枚举或指针类型,并返回操作数的值。对整型或枚举操作数执行整型提升。结果的类型与所提升的操作数一致。

charshortintlong都是整型。


12

没有使用+,结果会不同。下面的代码片段输出a 97而不是a a

char ch = 'a';
std::cout << ch << ' ' << +ch << '\n';

原因是因为不同的重载打印不同类型的数据。std::basic_ostream没有 basic_ostream& operator<<( char value ); 重载,这在页面末尾有解释。
字符和字符字符串参数(例如类型为 charconst char* 的参数)由 operator<<非成员重载 处理。使用成员函数调用语法(例如 std::cout.operator<<('c');)尝试输出字符将调用重载之一(2-4),并输出数值。尝试使用成员函数调用语法输出字符字符串将调用重载(7)并打印指针值。
当传递一个 char 变量时,将调用 非成员重载
template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<(
    basic_ostream<CharT,Traits>& os, char ch );

该函数输出代码点ch处的字符。

如果直接将charsigned charunsigned char传递到流中,则会打印出字符。如果尝试在上述行中删除+,则会发现它打印出一些“奇怪”的或不可见的字符,这并非人们所期望的。

如果要获取它们的数字值,您必须调用shortintlonglong long的重载。最简单的方法是使用一元加号+char提升为int。这是仅有的几种实用的应用之一一元加运算符。显式强制转换为int也可以正常工作。

许多人在SO上遇到了这个问题,例如


1
你是不是想说正号而不是负号? - Ruslan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接