c++ - prioridad - operadores relacionales en java
¿El operador unario+tiene algún uso práctico? (6)
¿Se incluyó el operador unario +
solo para simetría con el operador unario, o encuentra algún uso práctico en el código C ++?
Buscando aquí, encontré ¿Cuál es el propósito del operador único ''+'' en C? , pero los únicos escenarios útiles allí involucran macros de preprocesador. Es bueno saberlo, pero parecen ser situaciones menos comunes e involucran macros. ¿Hay algún caso de uso que involucre código C ++ más común?
El operador unario +
convierte un lvalue en un rvalue:
struct A {
static const int value = 1;
};
// ...
int x = std::min(0, A::value);
¡Oh no! Este código no se vinculará, porque alguien olvidó definir (así como declarar) A::value
. std::min
toma sus argumentos por referencia, por lo que A::value
debe tener una dirección para que una referencia pueda vincularse (técnicamente, la regla de una definición dice que debe definirse exactamente una vez en el programa).
No importa, unario más para el rescate:
int x = std::min(0, +A::value);
El plus unario crea un temporal con el mismo valor, y la referencia se enlaza con el temporal, por lo que podemos solucionar la definición que falta.
Esto no es algo que necesite con frecuencia, pero es un uso práctico del operador unario plus.
Si explícitamente se mantiene alejado de cualquier semántica de valor numérico para una clase, cualquier sobrecarga de operadores está clara para no "hacer lo que hacen los ints". En ese caso, el plus unario puede tener algún significado, haciendo mucho más que solo devolver *this
Ejemplo destacado: el plus de Boost.Spirit para Kleene Plus de EBNF incorporado genera una regla de analizador que permite que su argumento (una regla de analizador también) coincida una o más veces.
Simetría con unario -
no es del todo inútil; Se puede usar para enfatizar:
const int foo = -1;
const int bar = +1;
Y un unary sobrecargado se puede usar para denotar una operación que produce el mismo valor lógico que su operando, mientras se realiza algún cálculo no trivial. (He visto esto hecho para conversiones de tipos en Ada, lo que permite sobrecargar unario +
, pero no conversiones.) No tengo un buen ejemplo de C ++ a la mano, y se podría argumentar que sería un estilo pobre. (Por otra parte, he visto muchas críticas sobre la sobrecarga de <<
.)
En cuanto a la razón por la cual C ++ lo tiene, probablemente sea en gran medida por su consistencia con C, que lo agregó con el estándar ANSI de 1989. La justificación C simplemente dice:
Unary plus fue adoptado por el Comité C89 de varias implementaciones, por simetría con unario menos.
Un poco tarde, pero hay un uso muy retorcido con el que tropecé. Al parecer, el operador +
puede ser útil (si es que quizás no sea estrictamente necesario) al diseñar salvaguardas en torno a la posibilidad de encontrar tokens de preprocesador vacíos. Vea esta publicación para una discusión más profunda.
Es práctico, pero de ninguna manera agradable.
Unario + aplica promociones integrales. La respuesta de @PeteBecker muestra una manera que puede ser útil.
Por otra parte, tenga en cuenta que un tipo de enumeración sin ámbito se promueve a un tipo entero que puede representar todos los valores en la enum
. Por lo tanto, en C ++ 03, incluso sin el tipo std::underlying_type<T>
C ++ 11, podría hacer:
enum MyBitMask {
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4,
Flag4 = 0x8000000
};
inline MyBitMask operator&(MyBitMask x, MyBitMask y) {
return static_cast<MyBitMask>( +x & +y );
}
inline MyBitMask operator|(MyBitMask x, MyBitMask y) {
return static_cast<MyBitMask>( +x | +y );
}
char ch = ''a'';
std::cout << ch << ''/n'';
std::cout << +ch << ''/n'';
La primera inserción escribe el carácter a
para cout
. La segunda inserción escribe el valor numérico de ch
para cout
. Pero eso es un poco oscuro; se basa en que el compilador aplica promociones integrales para el operador +
.