【问题标题】: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 这是一项有用的技能,可以培养。

标签: c++ char unary-operator


【解决方案1】:

输出运算符&lt;&lt; 在传递char(有符号或无符号)时会将其写为字符。

这些函数将返回unsigned char 类型的值。并且如上所述,它将打印这些值在当前编码中表示的字符,而不是它们的整数值。

+ 运算符将这些函数返回的unsigned char 转换为int 到integer promotion。这意味着将打印整数值。

像+std::numeric_limits&lt;unsigned char&gt;::lowest() 这样的表达式本质上等于static_cast&lt;int&gt;(std::numeric_limits&lt;unsigned char&gt;::lowest())。

【讨论】:

    【解决方案2】:

    + 可以将unsigned char 变成int。 + 运算符是保值的,但它具有在其操作数上诱导积分提升的效果。这是为了确保您看到的是一个数值,而不是operator &lt;&lt; 在给定字符类型时会打印的一些(半)随机字符。

    【讨论】:

      【解决方案3】:

      只是为了添加对已经给出的答案的参考。来自CPP标准工作草案N4713:

      8.5.2.1 一元运算符
      ...

      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&amp; operator&lt;&lt;( char value ); 重载,页面末尾有说明

        字符和字符串参数(例如,char 或 const char* 类型)由 operator&lt;&lt; 的 non-member overloads 处理。尝试使用成员函数调用语法(例如,std::cout.operator&lt;&lt;('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 上遇到过这个问题

        【讨论】:

        • 你的意思是一元加,而不是减吗?
        猜你喜欢
        • 2021-09-17
        • 1970-01-01
        • 2012-03-07
        • 2011-04-06
        • 1970-01-01
        • 1970-01-01
        • 2012-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多