答案 0 :(得分:102)
实际上,一元加做做某事 - 即使在C语言中。它在操作数上执行 usual arithmetic conversions 并返回一个新值,该值可以是宽度更大的整数。如果原始值是宽度小于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是一个int”。
因此,在此示例中,一元加上使用不同类型的和签名创建了一个新值。
答案 1 :(得分:53)
如果你觉得有必要的话就会超载;对于所有预定义类型,它基本上是一个无操作。
无操作一元算术运算符的实际用途非常有限,并且倾向于与在算术表达式中使用值的后果相关,而不是与运算符本身相关。例如,它可以用于强制从较小的整数类型扩展到int
,或者确保表达式的结果被视为右值,因此与非const
引用参数不兼容。但是,我提出,这些用途更适合编码高尔夫而不是可读性。 : - )
答案 2 :(得分:33)
来自K&amp; R第二版:
一元+是ANSI标准的新功能。它被添加为与一元对称的对称 - 。
答案 3 :(得分:31)
我看到它用于清晰,强调正值与负值不同:
shift(+1);
shift(-1);
但这是一个非常弱的用途。答案肯定是超载。
答案 4 :(得分:24)
内置的一元+
做的一件事就是将左值变成右值。例如,你可以这样做
int x;
&x;
但你不能这样做
&+x;
:)
P.S。 “超载”绝对不是正确的答案。一元+
继承自C,并且C中没有用户级运算符重载。
答案 5 :(得分:14)
一元+完成的主要内容是对小于int的数据类型的int类型提升。如果您尝试使用std::cout
作为数字数据打印字符数据,这可能非常有用。
char x = 5;
std::cout << +x << "\n";
与
非常不同char x=5;
std::cout << x << "\n";
它也可用于重载,但实际上你的重载应该几乎是NOP。
答案 6 :(得分:10)
如果您需要打印原始字节的数值(例如,存储为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
这只是一个简单的例子。我确信还有一些时候,一元+可以帮助处理你的字节更像数字而不是文字。
答案 7 :(得分:4)
历史花絮。 C99标准化委员会还认为,一元加的现有用法相当罕见,正如他们考虑重复使用它来实现该语言的另一个特征:抑制浮点常数表达式的翻译时评估。请参阅C基本原理F.7.4节中的以下引用:
该规范的早期版本允许转换时间常数算术,但是 授权一元+运算符,当应用于操作数时,禁止转换时间 评估常数表达式。
最后,语义被颠倒了,在大多数情况下执行运行时评估(至少达到“似乎”规则),并且能够通过使用静态初始化程序来强制执行翻译时评估。请注意,主要区别在于浮点异常的出现,以及其他存在的浮点舍入或精度设置。
答案 8 :(得分:3)
不多。允许operator+()
重载的一般说法是,对于重载operator-()
肯定存在真正的世界用途,如果你是的话,那么非常很奇怪(或不对称)允许重载operator-()
而不是operator+()
。
我相信我第一次从Stroustrop那里读到了这个论点,但是我没有权利对我进行验证。我可能错了。
答案 9 :(得分:3)
一元加上出现在C中,它完全没有做任何事情(很像auto
关键字)。为了不拥有它,Stroustrup将不得不引入与C的无偿不兼容。
一旦它在C ++中,很自然地允许一个重载函数,就像一元减号一样,而Stroustrup可能因为那个原因而引入它,如果它还没有。
所以,它没有任何意义。它可以用作一种装饰,使事物看起来更加对称,例如使用+1.5与-1.5相反。在C ++中,它可以被重载,但如果operator+()
做任何事情,它会让人感到困惑。记住标准规则:当重载算术运算符时,请执行int
s之类的操作。
如果你正在寻找它存在的原因,那就找一些关于C的早期历史的东西。我怀疑没有充分的理由,因为C并没有真正的设计。考虑无用的auto
关键字(可能与static
形成对比,现在在C ++ 0x中被回收),以及entry
关键字,它从未做过任何事情(后来在C90中被省略) 。有一条着名的电子邮件,其中Ritchie或Kernighan说,当他们意识到运算符优先级有问题时,已经有三个安装了数千行代码而他们不想破解。
答案 10 :(得分:2)
我不能引用任何来源,但我已经明白它是用于显式类型提升,这意味着无损类型转换。这使它位于转换层次结构的顶部,
new_type operator+(old_type)
new_type(old_type)
operator(new_type)(old_type)
new_type operator=(old_type)
当然,这是我对15年前我读过的一本微软(非常旧的)c / c ++手册中的一个注释的解释,所以请大家用它。
答案 11 :(得分: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与一元+具有相同的优先级。
答案 12 :(得分:0)
我想你可以用它来做一个积极的数字。只需将一元+运算符重载为abs。除非你真的想混淆你的代码,否则不值得让你的开发人员感到困惑。然后它很好用。
答案 13 :(得分:0)
只是用来说服哪些数字为正数
例如;
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})
答案 14 :(得分:-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; }
}
}