Negative Values in User-Defined Literals
How do we handle negative values in user-defined literals?
Handling negative values in user-defined literals requires understanding the precedence rules in C++.
The key point is that the negation operator (-
) has lower precedence than user-defined literals. This means the literal function is called with a positive value first, and then the result is negated.
Example with Custom Types
Here's an example demonstrating this behavior with a custom Distance
type:
#include <iostream>
class Distance {
public:
Distance(float value) : value{value} {}
Distance operator-() const {
return Distance{-value};
}
float value;
};
std::ostream& operator<<(
std::ostream& os, Distance d) {
os << d.value << " meters\n";
return os;
}
Distance operator""_meters(long double val) {
return Distance{static_cast<float>(val)};
}
int main() {
Distance d1 = -5.0_meters;
std::cout << d1;
}
-5 meters
Precedence Rules
The above code works because:
5.0_meters
callsoperator""_meters
with5.0
as an argument.- The result is a
Distance
object with a value of5.0
. - The negation operator (
-
) is then applied to thisDistance
object, invoking the overloadedoperator-
function.
Handling Negative Values Directly
If you need to handle negative values within the literal itself, consider implementing appropriate logic within the literal function. However, this is uncommon and usually unnecessary due to the precedence rules.
Example with Integers
Here's an example with integer literals:
#include <iostream>
int operator""_km(unsigned long long val) {
return static_cast<int>(val * 1000);
}
int main() {
int distance = -3_km;
std::cout << distance << " meters\n";
}
-3000 meters
Common Pitfalls
- Order of Operations: Remember that the literal function is called first, and then the result is negated.
- Operator Overloading: Ensure that the type returned by your literal supports the unary operator if you need to handle negation.
Conclusion
Handling negative values in user-defined literals relies on understanding operator precedence.
The literal function processes the positive value first, and then the result can be negated. By correctly implementing and overloading the necessary operators, you can effectively manage negative values in your custom literals.
User Defined Literals
A practical guide to user-defined literals in C++, which allow us to write more descriptive and expressive values