91

一元加号运算符有什么作用?我找到了几个定义(herehere),但我仍然不知道它的用途。看起来它什么也没做,但这是有原因的,对吧?

4

15 回答 15

123

实际上,一元加号确实做了一些事情——即使在 C 中也是如此。它对操作数执行通常的算术转换并返回一个新值,该值可以是更大宽度的整数。如果原始值是一个宽度小于 的无符号整数int,它也会被更改为一个signed值。

通常这不是那么重要,但它产生影响,因此使用一元加号作为一种表示整数为正的“注释”并不是一个好主意。考虑以下 C++ 程序:

void foo(unsigned short x)
{
 std::cout << "x is an unsigned short" << std::endl;
}

void foo(int x)
{
 std::cout << "x is an int" << std::endl;
}

int main()
{
 unsigned short x = 5;
 foo(+x);
}

这将显示“x is an int”。

所以在这个例子中,一元加号创建了一个具有不同类型符号的新值。

于 2010-10-11T02:07:07.233 回答
60

如果您觉得需要,它就会超载;对于所有预定义类型,它本质上是无操作的。

无操作一元算术运算符的实际用途非常有限,并且往往与在算术表达式中使用值的结果有关,而不是与运算符本身有关。例如,它可用于强制从较小的整数类型扩展为int,或确保表达式的结果被视为右值,因此与非const引用参数不兼容。然而,我认为这些用途比可读性更适合编码高尔夫。:-)

于 2009-04-07T20:45:58.160 回答
43

来自 K&R 第二版:

一元 + 是 ANSI 标准的新符号。添加它是为了与一元 - 对称。

于 2011-09-30T14:07:20.420 回答
38

我已经看到它用于清晰,强调正值与负值不同:

shift(+1);
shift(-1);

但这是一个相当弱的用途。答案肯定是超载。

于 2009-04-07T20:56:28.447 回答
29

内置一元+所做的一件事是将左值转换为右值。例如,您可以这样做

int x;
&x;

但你不能这样做

&+x;

:)

PS“重载”绝对不是正确的答案。一元+是从 C 继承的,C 中没有用户级运算符重载。

于 2010-10-11T03:58:39.190 回答
14

一元 + 完成的主要事情是将小于 int 数据类型的类型提升为 int。如果您尝试使用std::cout数字数据打印 char 数据,这将非常有用。

char x = 5;
std::cout << +x << "\n";

char x=5;
std::cout << x << "\n";

它也可用于重载,但实际上您的重载应该几乎是 NOP。

于 2010-10-11T03:42:20.827 回答
12

如果您出于调试或任何原因需要打印原始字节的数值(例如,存储为 char 的小数),一元 + 可以简化打印代码。考虑

char c = 42;
cout << c << endl;           // prints "*\n", not what you want in this case
cout << (int)c << endl;      // prints "42\n", ok
cout << +c << endl;          // prints "42\n", much easier to type

这只是一个简单的例子。我确信在其他时候一元 + 可以帮助您将字节更像数字而不是文本。

于 2012-08-05T00:59:44.637 回答
4

一个历史花絮。C99 标准化委员会还认为一元加法的现有用途相当少见,他们考虑重用它以实现语言中的另一个特性就证明了这一点:抑制浮点常量表达式的翻译时求值。请参阅 C 基本原理,第 F.7.4 节中的以下引用:

该规范的早期版本允许翻译时常量算术,但授权一元 + 运算符,当应用于操作数时,禁止常量表达式的翻译时求值。

最后,语义被颠倒了,在大多数上下文中强制执行运行时评估(至少达到“好像”规则),并且能够通过使用静态初始化器来强制执行翻译时评估。请注意,主要区别在于浮点异常的发生以及其他浮点舍入或精度设置(如果存在)。

于 2012-07-16T02:39:54.947 回答
3

不多。允许重载的一般论点operator+()是,重载肯定有现实世界的用途,如果你允许重载但不允许重载operator-(),那将是非常奇怪的(或不对称的) 。operator-()operator+()

我相信我首先从 Stroustrop 那里读到了这个论点,但我没有我的书来验证它。我可能错了。

于 2009-04-10T17:05:23.257 回答
3

一元加号出现在 C 中,它完全没有做任何事情(很像auto关键字)。为了不拥有它,Stroustrup 将不得不引入与 C 的无缘无故的不兼容。

一旦它出现在 C++ 中,就很自然地允许重载函数,就像一元减法一样,如果它还没有的话,Stroustrup 可能会因为这个原因引入它。

所以,没什么意思。它可以用作一种装饰,使事物看起来更对称,例如使用 +1.5 与 -1.5 相反。在 C++ 中,它可以被重载,但如果operator+()做任何事情会令人困惑。记住标准规则:当重载算术运算符时,像ints 那样做。

如果您正在寻找它存在的原因,请查找有关 C 早期历史的一些信息。我怀疑没有充分的理由,因为 C 并不是真正设计的。考虑无用auto关键字(可能与static,现在在 C++0x 中被回收)和entry关键字,它从来没有做任何事情(后来在 C90 中被省略)。有一封著名的电子邮件,Ritchie 或 Kernighan 说,当他们意识到运算符优先级存在问题时,已经有 3 个安装有数千行代码,他们不想破坏。

于 2009-04-10T17:53:41.173 回答
2

我不能为此引用任何来源,但我已经明白它是用于显式类型提升,这意味着无损类型转换。这使它位于转换层次结构的顶部,

  • 晋升: new_type operator+(old_type)
  • 转换: new_type(old_type)
  • 投掷: operator(new_type)(old_type)
  • 强迫: new_type operator=(old_type)

当然,这是我对大约 15 年前阅读的一本微软(非常老的)c/c++ 手册中的注释的解释,因此请谨慎对待。

于 2009-04-10T18:04:51.333 回答
1
#include <stdio.h>
int main()
{
    unsigned short x = 5;
    printf ("%d\n",sizeof(+x)); 
    printf ("%d\n",sizeof(x)); 
    return 0;
}

如上例所示,一元 + 确实改变了类型,大小分别为 4 和 2。奇怪的是表达式 +x 确实是在 sizeof 中计算的,我认为这不应该。也许是因为 sizeof 与一元 + 具有相同的优先级。

于 2015-03-29T23:20:29.670 回答
-1

编辑完全重写,因为我在我原来的答案中很糟糕。

这应该允许您将类型的显式声明处理为正值(我认为主要是非数学运算)。似乎否定会更有用,但我想这是一个可能会产生影响的例子:

public struct Acceleration
{
    private readonly decimal rate;
    private readonly Vector vector;

    public Acceleration(decimal rate, Vector vector)
    {
        this.vector = vector;
        this.rate = rate;
    }

    public static Acceleration operator +(Acceleration other)
    {
        if (other.Vector.Z >= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public static Acceleration operator -(Acceleration other)
    {
        if (other.Vector.Z <= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public decimal Rate
    {
        get { return rate; }
    }

    public Vector Vector
    {
        get { return vector; }
    }
}
于 2009-04-07T20:49:23.097 回答
-1

我想您可以使用它来始终使数字为正数。只需将一元 + 运算符重载为 abs。真的不值得混淆你的开发者伙伴,除非你真的只是想混淆你的代码。然后它会很好地工作。

于 2009-04-07T20:52:18.037 回答
-1

只是用来说服哪些数字是正数的

例如;

int a=10;
System.out.println(+x);// prints 10(that means,that number 10 multiply by +1,{10*+1})

//if we use unary minus

int a=10;
System.out.println(-x);//prints -10(that means,that number 10 multiply by +1,{10*-1})
于 2019-11-08T04:39:29.020 回答