Does the unary + operator have any practical use?

血红的双手。 提交于 2019-11-28 11:53:08
char ch = 'a';
std::cout << ch << '\n';
std::cout << +ch << '\n';

The first insertion writes the character a to cout. The second insertion writes the numeric value of ch to cout. But that's a bit obscure; it relies on the compiler applying integral promotions for the + operator.

Symmetry with unary - isn't entirely useless; it can be used for emphasis:

const int foo = -1;
const int bar = +1;

And an overloaded unary + can be used to denote an operation that yields the same logical value as its operand, while performing some non-trivial computation. (I've seen this done for type conversions in Ada, which permits unary +, but not conversions, to be overloaded.) I don't have a good C++ example to hand, and one could argue that it would be poor style. (Then again, I've seen plenty of rants about overloading <<.)

As for why C++ has it, it's probably largely for consistency with C, which added it with the 1989 ANSI standard. The C Rationale just says:

Unary plus was adopted by the C89 Committee from several implementations, for symmetry with unary minus.

If you explicitly stay clear of any number value semantics for a class, any operator overloading is clear not to "do as the ints do". In that case, the unary plus may get any meaning, doing much more than just returning *this

Prominent example: Boost.Spirit's unary plus for the embedded EBNF's Kleene Plus generates a parser rule that lets it's argument (a parser rule as well) match one or more times.

The unary + operator turns a lvalue into an rvalue:

struct A {
  static const int value = 1;
};

// ...

int x = std::min(0, A::value);

Oh noes! This code won't link, because someone forgot to define (as well as declare) A::value. std::min takes its arguments by reference so A::value must have an address so a reference can bind to it (technically, the one definition rule says it must be defined exactly once in the program.)

Nevermind, unary plus to the rescue:

int x = std::min(0, +A::value);

The unary plus creates a temporary with the same value, and the reference binds to the temporary, so we can work around the missing definition.

This isn't something you need often, but it is a practical use of the unary plus operator.

Unary + applies integral promotions. @PeteBecker's answer shows one way that can be useful.

For another, note that an unscoped enumeration type gets promoted to an integer type which can represent all values in the enum. So in C++03, even without C++11's std::underlying_type<T>, you could do:

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

A bit late, but here's a very twisted use that I stumbled across. Apparently the + operator can be useful (if perhaps not strictly necessary) when designing safeguards around the possibility of encountering empty preprocessor tokens. See this post for a more in-depth discussion.

It's practical, but by no means pleasant.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!