一元加运算符做什么?

一元加运算符做什么?有几个定义,我已经找到(给你给你) ,但我仍然不知道它将用于什么。看起来好像没什么作用但这是有原因的,对吧?

57376 次浏览

It's there to be overloaded if you feel the need; for all predefined types it's essentially a no-op.

The practical uses of a no-op unary arithmetic operator are pretty limited, and tend to relate to the consequences of using a value in an arithmetic expression, rather than the operator itself. For example, it can be used to force widening from smaller integral types to int, or ensure that an expression's result is treated as an rvalue and therefore not compatible with a non-const reference parameter. I submit, however, that these uses are better suited to code golf than readability. :-)

EDIT Rewrote completely, because I was waaaayyy off in my original answer.

This should allow you to handle the explicit declaration of your type as a positive value (I think in mostly non-mathematical operations). It seems that negation would be more useful, but I guess here's an example of where it might make a difference:

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; }
}
}

I suppose you could use it to always make a number positive. Just overload the unary + operator to be abs. Not really worth confusing your fellow developers, unless you really just want to obfuscate your code. Then it'd work nicely.

I've seen it used for clarity, to emphasize the positive value as distinct from a negative value:

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

But that's a pretty weak use. The answer is definitely overloading.

Not much. The general argument for allowing the overload of operator+() is that there are definitely real world uses for overloading operator-(), and it would be very weird (or asymmetrical) if you were to allow overloading operator-() but not operator+().

I believe that I first read this argument from Stroustrop, but I don't have my books with me right to verify it. I might be wrong.

Unary plus was present in C, where it did absolutely nothing (much like the auto keyword). In order to not have it, Stroustrup would have had to introduce a gratuitous incompatibility with C.

Once it was in C++, it was natural to allow an overload function, just like unary minus, and Stroustrup might have introduced it for that reason if it wasn't already there.

So, it means nothing. It can be used as as sort of decoration to make things look more symmetrical, using +1.5 as the opposite to -1.5 for example. In C++, it can be overloaded, but it's going to be confusing if operator+() does anything. Remember the standard rule: when overloading arithmetic operators, do things like the ints do.

If you're looking for a reason why it's there, find something about the early history of C. I suspect there was no good reason, as C was not really designed. Consider the useless auto keyword (presumably in contrast to static, now being recycled in C++0x), and the entry keyword, which never did anything (and later omitted in C90). There's a famous email in which Ritchie or Kernighan say that, when they realized the operator precedence had problems, there were already three installations with thousands of lines of code that they didn't want to break.

I can't cite any source for this, but I have come to understand it is for explicit type promotion, which implies lossless type conversion. That puts it at the top of the conversion hierarchy,

  • Promotion: new_type operator+(old_type)
  • Conversion: new_type(old_type)
  • Cast: operator(new_type)(old_type)
  • Coercion: new_type operator=(old_type)

Of course, that's from my interpretation of a note in one of the microsoft (really old) c/c++ manuals that I read about 15 years ago, so take it with a grain of salt.

Actually, unary plus does do something - even in C. It performs the usual arithmetic conversions on the operand and returns a new value, which can be an integer of greater width. If the original value was an unsigned integer of lesser width than int, it will be changed to a signed value as well.

Usually this isn't that important, but it can have an effect, so it's not a good idea to use unary plus as a sort of "comment" denoting that an integer is positive. Consider the following C++ program:

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);
}

This will display "x is an int".

So in this example unary plus created a new value with a different type and signedness.

The main thing unary + accomplishes is type promotion to an int for smaller-than-int data types. This can be quite useful if you're trying to print char data using std::cout as numeric data.

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

is very different from

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

It's also available for overloading, but in practice your overload should be nearly a NOP.

One thing the built-in unary + does is turning lvalue into an rvalue. For example, you can do this

int x;
&x;

but you can't do this

&+x;

:)

P.S. "Overloading" is definitely not the right answer. Unary + was inherited from C and there's no user-level operator overloading in C.

From K&R second edition:

The unary + is new with the ANSI standard. It was added for symmetry with the unary -.

A historical tidbit. The C99 standardization committee also thought existing uses of unary plus were fairly rare, as evidenced by their considering reusing it to achieve another feature in the language: inhibition of translation-time evaluation of floating-point constant expressions. See the following quote from the C Rationale, section F.7.4:

An early version of this specification allowed translation-time constant arithmetic, but empowered the unary + operator, when applied to an operand, to inhibit translation-time evaluation of constant expressions.

In the end, the semantics were reversed, with run-time evaluation enforced in most contexts (at least up to the "as if" rule), and the ability to enforce translation-time evaluation by the use of static initializers. Note that the main difference lies in the occurrence of floating point exceptions, and other floating point rounding or precision settings, where present.

If you ever need to print the numeric value of raw bytes (eg, small numbers stored as char) for debug or whatever reason, unary + can simplify the print code. Consider

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

This is just a quick example. I am sure there are other times when unary + can help treat your bytes more like numbers instead of like text.

#include <stdio.h>
int main()
{
unsigned short x = 5;
printf ("%d\n",sizeof(+x));
printf ("%d\n",sizeof(x));
return 0;
}

As shown in the example above, the unary + really changes the type, size 4 and 2 respectively. Weird that the expression +x is indeed calculated in the sizeof, I thought that was not supposed to. Perhaps it's due to the fact that sizeof has the same priority as the unary +.

simply that used to convince which numbers are positive

eg;

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})