Pregunta

¿Qué hace el operador de suma unaria? Hay varias definiciones que he encontrado ( aquí y aquí ) pero todavía no tienen idea de lo que sería utilizado para. Parece como si no hace nada, pero tiene una razón para ello, ¿verdad?

¿Fue útil?

Solución

Es allí para ser sobrecargado si se siente la necesidad; para todos los tipos predefinidos que es esencialmente un no-op.

Los usos prácticos de un operador aritmético unario no-op son bastante limitadas, y tienden a relacionarse con las consecuencias del uso de un valor en una expresión aritmética, más que el propio operador. Por ejemplo, puede ser utilizado para forzar la ampliación de tipos integrales más pequeños para int, o asegurarse de que el resultado de una expresión se trata como un valor p y por lo tanto no es compatible con un parámetro de referencia no const. A mi juicio, sin embargo, que estos usos se adaptan mejor al golf código de legibilidad. : -)

Otros consejos

En realidad, unario más hace hacer algo - incluso en C. Se lleva a cabo la aritmética usual conversiones en el operando y devuelve un nuevo valor, que puede ser un número entero de mayor anchura. Si el valor original de un entero sin signo de menor anchura que int, se cambia a un valor signed también.

Por lo general, esto no es tan importante, pero puede tiene un efecto, por lo que es no una buena idea utilizar unario más como una especie de "comentarios" que denota que un número entero es positivo. Considere el siguiente programa en 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);
}

Esto mostrará "x es un entero".

Así que en este ejemplo unario mas creado un nuevo valor con un tipo diferente y de signo.

Desde K & R segunda edición:

  

El unario + es una novedad de la norma ANSI. Fue añadida a la simetría con la unario -.

He visto que se usa para mayor claridad, hacer hincapié en el valor positivo a diferencia de un valor negativo:

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

Pero eso es un uso bastante débil. La respuesta es, sin duda sobrecargando.

Una cosa que el + unario incorporada hace se está convirtiendo en un valor-valor p. Por ejemplo, se puede hacer esto

int x;
&x;

pero no se puede hacer esto

&+x;

:)

P.S. "Sobrecarga" definitivamente no es la respuesta correcta. + unario fue heredado de C y no hay operador de nivel de usuario la sobrecarga en C.

Lo principal es unario + logra tipo de promoción a un int para los tipos de datos más pequeños de lo int. Esto puede ser muy útil si usted está tratando de imprimir los datos CHAR utilizando std::cout como datos numéricos.

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

es muy diferente de

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

También está disponible para la sobrecarga, pero en la práctica su sobrecarga debe ser casi un NOP.

Si alguna vez tiene que imprimir el valor numérico de bytes primas (por ejemplo, pequeños números almacenados como char) para la depuración o la razón que sea, unario + puede simplificar el código de impresión. Considere

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

Esto es sólo un ejemplo rápido. Estoy seguro de que hay otros momentos en unario + puede ayudar a tratar su bytes más como números en lugar de texto similares.

Un dato histórico. El comité de normalización C99 también pensó usos existentes de unario mas eran bastante raras, como lo demuestra su reutilización teniendo en cuenta que para lograr otra característica en el idioma: inhibición de la evaluación en tiempo traducción de expresiones constantes de punto flotante. Ver la siguiente cita de la C Justificación, la sección F.7.4:

  

Una primera versión de esta especificación permite la traducción en tiempo aritmética constante, pero   facultado el operador unario +, cuando se aplica a un operando, para inhibir la traducción en tiempo   evaluación de expresiones constantes.

Al final, la semántica se invirtieron, con la evaluación en tiempo de ejecución forzada en la mayoría de los contextos (por lo menos hasta el "como si" regla), y la capacidad para hacer cumplir la evaluación en tiempo de traducción mediante el uso de inicializadores estáticos. Tenga en cuenta que la principal diferencia radica en la aparición de excepciones de punto flotante, y otros ajustes de redondeo de punto flotante de precisión o, si está presente.

No mucho. El argumento general para permitir la sobrecarga de operator+() es que hay mundo definitivamente real utiliza para sobrecargar operator-(), y sería muy raro (o asimétrica) si se va a permitir que la sobrecarga operator-() pero no operator+().

Creo que leí por primera vez este argumento de Stroustrop, pero no tengo mis libros conmigo derecho a verificarlo. Puedo estar equivocado.

Unario además estuvo presente en C, donde se hizo absolutamente nada (al igual que la palabra clave auto). Con el fin de no tenerlo, BS habría tenido que introducir una incompatibilidad con C gratuita.

Una vez que estaba en C ++, era natural para permitir una función de sobrecarga, al igual que menos unitario, y BS podría haber introducido por esa razón si no estaba ya allí.

Por lo tanto, no significa nada. Se puede utilizar como como una especie de decoración para hacer las cosas se ven más simétrico, utilizando 1,5 como lo opuesto a -1.5 por ejemplo. En C ++, también puede sobrecargarse, pero va a ser confuso si operator+() hace nada. Recuerde la regla estándar:., Cuando la sobrecarga de operadores aritméticos, hacer cosas como las hacen ints

Si usted está buscando una razón por la que está ahí, encontrar algo sobre la historia temprana de C. Sospecho que no había ninguna buena razón, ya que C no estaba diseñada. Considere la palabra clave auto inútil (presumiblemente en contraste con static, que está siendo reciclada en C ++ 0x), y la palabra clave entry, que nunca hizo nada (y más tarde omite en C90). Hay un famoso correo electrónico en el que Ritchie o Kernighan dicen que, cuando se dieron cuenta de la prioridad de los operadores tenía problemas, ya había tres instalaciones con miles de líneas de código que no quieren romper.

No puedo citar ninguna fuente para esto, pero he llegado a comprender que es para la promoción explícita de tipos, lo que implica la conversión del tipo sin pérdidas. Eso lo pone en la parte superior de la jerarquía de la conversión,

  • Promoción: new_type operator+(old_type)
  • Conversión: new_type(old_type)
  • Reparto: operator(new_type)(old_type)
  • La coacción: new_type operator=(old_type)

Por supuesto, eso es de mi interpretación de una nota en uno de los de Microsoft (muy viejo) C / C ++ manuales que leí hace unos 15 años, por lo que tomar con un grano de sal.

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

Como se muestra en el ejemplo anterior, el unario + realmente cambia el tipo, tamaño 4 y 2 respectivamente. Raro que la expresión x + se calcularon efectivamente en el sizeof, pensé que no debía. Quizás es debido al hecho de que sizeof tiene la misma prioridad que el unario +.

supongo que se podría utilizar para hacer siempre un número positivo. Sólo sobrecargar el operador unario + ser abs. No merece la pena confundir al resto de desarrolladores, a menos que realmente sólo quiere ocultar su código. Luego se iba a trabajar muy bien.

Editar Se reescribió por completo, porque yo estaba fuera waaaayyy en mi respuesta original.

Esto debería permitir que usted resuelva la declaración explícita de su tipo como un valor positivo (creo que en la mayoría de las operaciones no matemáticos). Parece que la negación sería más útil, pero supongo que aquí es un ejemplo de que podría hacer una diferencia:

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; }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top