In MSVC chrono implementation I see the following code
_EXPORT_STD template <int = 0>
_NODISCARD constexpr year_month operator+(const year_month& _Left, const months& _Right) noexcept {
const auto _Mo = static_cast<long long>(static_cast<unsigned int>(_Left.month())) + (_Right.count() - 1);
const auto _Div = (_Mo >= 0 ? _Mo : _Mo - 11) / 12;
return year_month{_Left.year() + years{_Div}, month{static_cast<unsigned int>(_Mo - _Div * 12 + 1)}};
}
Can someone explain me why it uses template with unnamed parameter ?
You have two very similar overloads for operator+, originally without the template
template <int = 0>
constexpr year_month operator+(const year_month& _Left, const months& _Right) noexcept
constexpr year_month operator+(const year_month& _Left, const years& _Right) noexcept
It was discovered that if you have a value that is convertible to both months and years, there was an ambiguity here. Which conversion should be chosen?
By making one of the operators (a dummy) template, the non-template is chosen (if possible) because templates have lower priority in overload resolution.
The standard specifies this requirement a bit convoluted (backwards in my opinion):
"If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months"
So if the conversions are equally good, the non-template is to be chosen. Only if conversion to months is better, the template gets a chance.
(And the standard doesn't explicitly say that is has to be a template, but that is a way of implementing this requirement).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With