Reputation: 1764
Suppose I want to define an integer literal which also allows for negative values, e.g. -12_km
.
I.e., I would like to do
using coord_t = long long;
coord_t operator "" _km(long long int);
However, this is not accepted by my compiler (gcc).
The standard mentions a list of the allowed types for the parameter list of such a literal operator, but no signed integer type is among them.
Why is the standard like that? Why doesn't it allow for user-defined signed integer literals?
Upvotes: 2
Views: 461
Reputation: 170044
Because there are no negative integer literals in the grammar. Let's put aside the user-defined nature of your question. When we write -12
, it's the literal 12
, which has unary -
applied to it. The grammatical definition of an integer literal contains no mention of a minus sign.
[lex.icon] (redacted and edited)
integer-literal: decimal-literal integer-suffix decimal-literal: nonzero-digit decimal-literal digit nonzero-digit: one of 1 2 3 4 5 6 7 8 9 digit: one of 0 1 2 3 4 5 6 7 8 9
It's right there in the grammar. There are no productions that produce negative integer literal. And that is why user-defined literals follow the same convention. Their grammar production simply reuses the production for an integer literal
user-defined-literal: user-defined-integer-literal user-defined-integer-literal: decimal-literal ud-suffix
Since negation is always an expression other than a literal, you need to overload the appropriate operator for coord_t
. And by the way, the same applies for +12
. It's a unary plus applied to 12
, not a literal by itself.
Upvotes: 3
Reputation: 41753
Because there are no negative integer literals in C++. -12
is actually the minus operator applying to the positive literal 12
. That's the very reason why
INT_MIN
as -INT_MAX - 1
-2147483648 > 0
and 0 < -0x80000000
in some compilersSo you need to overload the unary minus operator to use -12_km
coord_t operator "" _km(unsigned long long);
coord_t operator-();
Upvotes: 2