在调用 std::numeric_limits<unsigned char> 成员之前,一元“+”的目的是啥?
Posted
技术标签:
【中文标题】在调用 std::numeric_limits<unsigned char> 成员之前,一元“+”的目的是啥?【英文标题】:What is the purpose of a unary "+" before a call to std::numeric_limits<unsigned char> members?在调用 std::numeric_limits<unsigned char> 成员之前,一元“+”的目的是什么? 【发布时间】:2019-02-08 07:06:34 【问题描述】:我看到this example in cppreference's documentation for 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()
我已经测试过了,用“-”替换它,这也有效。 这样的“+”运算符有什么用?
【问题讨论】:
试试看。如果省略+
,你会得到什么?
如果代码的编写者愿意解释它的含义或使用显式强制转换,那么这个问题将不需要来询问...
如果您替换为 -
,则输出将不是限制的正确值
为了记录,如果你想自己谷歌这种东西,这被称为“一元加号”运算符——它是一元的,因为它需要一个值(在这种情况下,东西紧随其后),并且“加号”是 Google 友好的表示 +
的方式。在这种情况下,您的查询可能是“c++ unary plus”。它......不是很直观,你仍然需要学习阅读你会找到的文档,但 IMO 这是一项有用的技能,可以培养。
【参考方案1】:
输出运算符<<
在传递char
(有符号或无符号)时会将其写为字符。
这些函数将返回unsigned char
类型的值。并且如上所述,它将打印这些值在当前编码中表示的字符,而不是它们的整数值。
+
运算符将这些函数返回的unsigned char
转换为int
到integer promotion。这意味着将打印整数值。
像+std::numeric_limits<unsigned char>::lowest()
这样的表达式本质上等于static_cast<int>(std::numeric_limits<unsigned char>::lowest())
。
【讨论】:
【参考方案2】:+
可以将unsigned char
变成int
。 +
运算符是保值的,但它具有在其操作数上诱导积分提升的效果。这是为了确保您看到的是一个数值,而不是operator <<
在给定字符类型时会打印的一些(半)随机字符。
【讨论】:
【参考方案3】:只是为了添加对已经给出的答案的参考。来自CPP标准工作草案N4713:
8.5.2.1 一元运算符 ...
一元 + 运算符的操作数应具有算术、无范围枚举或指针类型,结果是参数的值。 对整数或枚举操作数执行整数提升。结果的类型是提升的操作数的类型。
而char
、short
、int
和long
是整数类型。
【讨论】:
【参考方案4】:没有+
,结果会有所不同。以下 sn -p 输出 a 97
而不是 a a
char ch = 'a';
std::cout << ch << ' ' << +ch << '\n';
原因是不同的重载打印不同类型的数据。
std::basic_ostream
没有 basic_ostream& operator<<( char value );
重载,页面末尾有说明
字符和字符串参数(例如,
char
或const char*
类型)由operator<<
的 non-member overloads 处理。尝试使用成员函数调用语法(例如,std::cout.operator<<('c');
)输出字符将调用重载之一(2-4)并输出数值。尝试使用成员函数调用语法输出字符串将调用重载 (7) 并打印指针值。
传递char
变量时将调用的non-member overload 是
template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<(
basic_ostream<CharT,Traits>& os, char ch );
打印出代码点ch
处的字符
所以基本上如果你将char
、signed char
或unsigned char
直接传递给流,它会打印出字符。如果您尝试删除上述行中的+
,您会看到它会打印一些“奇怪”或不可见的字符,这不是人们所期望的
如果您想要它们的数值,则必须调用 short
、int
、long
或 long long
的重载。最简单的方法是从char
升级到int
,一元加+
。这是unary plus operator 中的rare useful applications 之一。对int
的显式转换也可以使用
有很多人在 SO 上遇到过这个问题
cout not printing unsigned char std::cout deal with uint8_t as a character uint8_t can't be printed with cout【讨论】:
你的意思是一元加,而不是减吗?以上是关于在调用 std::numeric_limits<unsigned char> 成员之前,一元“+”的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章
C++/C++11中std::numeric_limits的使用
val != std::numeric_limits<double>::infinity() 或 !isinf(val) 或 isfinite(val)