Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why use template in year_month class?

Tags:

c++

c++-chrono

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 ?

like image 864
Joseph Perez Avatar asked Nov 17 '25 03:11

Joseph Perez


1 Answers

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).

like image 75
BoP Avatar answered Nov 18 '25 17:11

BoP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!