Reputation: 11045
Was the unary +
operator only included for symmetry with the unary -
operator, or does it find some practical use in C++ code?
Searching here, I came across What is the purpose of the unary '+' operator in C?, but the only useful scenarios there involve preprocessor macros. Those are good to know, but they seem to be some less common situations, and involve macros. Are there any use cases involving more common C++ code?
Upvotes: 33
Views: 3931
Reputation: 16242
Since for arithmetic variables operator+ generates a new value, I use it in general to generate value copies of reference-like (proxy) types.
template<class T> class ref_of{
T* impl_; // or a more complicated implementation
public:
T operator+() const{return *impl_;}
operator T&()&{return *impl_;}
}
...
ref_of<T> r = t;
auto s = +r; // this forces a copy
Another option is to use operator*
but then the ref_of
can be confused with a pointer-like object.
Upvotes: 0
Reputation: 96286
Among other things, +
converts lambdas to function pointers. Normally the conversion happens automatically, but sometimes it doesn't.
For example, this doesn't compile:
std::array arr{
[](int x){return x*x;},
[](int x){return x*x*x;},
};
You could make it work by specifying the function pointer type as the std::array
template parameter, or you could just do this:
std::array arr{
+[](int x){return x*x;},
+[](int x){return x*x*x;},
};
Upvotes: 3
Reputation: 16242
Since for arithmetic variables operator+ generates a new value. I use it to generate value copies of reference-like (proxy) types.
template<class T> class ref_of{
T* impl_; // or a more complicated implementation
public:
T operator+() const{return *impl_;}
operator T&()&{return *impl_;}
}
Another option is to use operator*
but then the ref_of
can be confused with a pointer-like object.
Upvotes: 0
Reputation: 14313
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.
Upvotes: 1
Reputation: 171303
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.
Upvotes: 7
Reputation: 72356
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 );
}
Upvotes: 4
Reputation: 76315
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.
Upvotes: 37
Reputation: 24606
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.
Upvotes: 11
Reputation: 263307
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.
Upvotes: 23