一元加运算符是做什么的?
一元加运算符是做什么的? 有几个定义,我已经find( 这里和这里 ),但我仍然不知道它将用于什么。 看起来它没有做任何事情,但有一个原因,对吧?
如果你觉得有需要的话,那里就会超负荷; 对于所有预定义的types,它本质上是一个无操作。
无操作一元算术运算符的实际用途相当有限,往往涉及在算术expression式中使用值的后果,而不是操作符本身。 例如,它可以用于强制从较小的整型到int
拓宽,或者确保expression式的结果被视为右值,因此不与非常量引用参数兼容。 然而,我认为这些用途比可读性更适合编码高尔夫。 🙂
实际上,一元加操作也会做一些事情 – 即使是在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是一个整数”。
所以在这个例子中,一元加号创build了一个具有不同types和签名的新值。
我已经看到它是为了清晰起见,强调正面价值与负面价值不同:
shift(+1); shift(-1);
但这是一个非常薄弱的用途。 答案肯定是重载。
从K&R第二版开始:
一元+是ANSI标准新增的。 它被添加为与一元对称。
内置的一元+
所做的一件事是把左值变成右值。 例如,你可以做到这一点
int x; &x;
但是你不能这样做
&+x;
🙂
PS“Overloading”绝对不是正确的答案。 一元+
是从Cinheritance的,并且在C中没有用户级的操作符重载。
一元+完成的主要事情是将types提升为int小于inttypes的数据types。 如果您试图使用std::cout
作为数字数据来打印char数据,这可能会非常有用。
char x = 5; std::cout << +x << "\n";
是非常不同的
char x=5; std::cout << x << "\n";
它也可用于超载,但在实践中,你的超载应该几乎是一个NOP。
如果您需要打印原始字节的数字值(例如,以charforms存储的小数字)以进行debugging或任何原因,则一元+可以简化打印代码。 考虑
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
这只是一个简单的例子。 我相信还有其他的时候,一元+可以帮助把你的字节更像数字,而不是像文本。
不多。 允许operator+()
的重载的一般论据是,确实存在重载operator-()
现实世界的用法,如果你允许重载operator-()
而不是operator+()
operator-()
,那将是非常奇怪的(或不对称的) operator+()
。
我相信我首先从Stroustrop那里读到了这个论点,但是我没有我的书来对它进行validation。 我可能错了。
一元加在C中出现,它完全没有(很像auto
关键字)。 为了没有它,Stroustrup本来不得不引入与C无关的不兼容性。
一旦它在C ++中,允许一个重载函数就像一元减号一样是自然的,而Stroustrup可能因为这个原因而引入它,如果它不在那里的话。
所以,这意味着什么。 它可以被用来作为一种装饰,使事物看起来更对称,例如使用+1.5作为-1.5的对立面。 在C ++中,它可以被重载,但是如果operator+()
做了任何事情,将会令人困惑。 记住标准规则:当重载算术运算符时,像int
这样的事情可以做。
如果你正在寻找一个为什么它存在的原因,找一些关于C的早期历史。我怀疑没有什么好的理由,因为C没有真正的devise。 考虑一下无用的auto
关键字(可能与static
对比,现在正在C ++ 0x中回收)和entry
关键字,它们从来没有做过任何事情(后来在C90中被省略)。 有一封着名的电子邮件,Ritchie或Kernighan说,当他们意识到运营商的优先顺序出现问题时,已经有三次安装了数千行代码,他们不想破坏。
一个历史的珍闻。 C99标准化委员会也认为,一元加法的现有用法相当罕见,他们考虑再次使用它来实现另一个语言function:抑制浮点常量expression式的翻译时间评估。 请参见C原理第F.7.4节中的以下引用:
本规范的早期版本允许转换时间常数算术,但赋予一元+运算符(当应用于操作数时)来抑制常量expression式的转换时间评估。
最后,语义被颠倒过来,运行时评估在大多数情况下(至less达到“asf”规则),以及通过使用静态初始化器强制执行翻译时评估的能力。 请注意,主要区别在于浮点exception的发生,以及其他浮点舍入或精度设置。
我不能引用任何来源,但我已经明白这是明确的types提升,这意味着无损types转换。 这使得它位于转换层次结构的顶部,
- 推广:
new_type operator+(old_type)
- 转换:
new_type(old_type)
- 演员:
operator(new_type)(old_type)
- 强制:
new_type operator=(old_type)
当然,那是我在15年前阅读的微软(真正的老)c / c ++手册之一的一个笔记的解释,所以拿一粒盐。
#include <stdio.h> int main() { unsigned short x = 5; printf ("%d\n",sizeof(+x)); printf ("%d\n",sizeof(x)); return 0; }
如上例所示,一元+实际上分别改变了types,大小4和2。 奇怪的是,expression式+ x的确是在sizeof中计算的,我以为这是不应该的。 也许这是由于sizeof与一元+具有相同的优先级。
我想你可以用它来总是让一个积极的数字。 只需将一元+运算符超载为abs。 除非你真的只是想混淆你的代码,否则不值得让你的开发人员感到困惑。 那么它会很好地工作。
编辑彻底重写,因为我waaaayyy在我原来的答案。
这应该允许你处理你的types的显式声明作为一个正值(我认为在大多数非math操作)。 看来,否定会更有用,但我想这里是一个例子,它可能会有所作为:
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; } } }