why use template in year_month class?

why use template in year_month class?


17

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 ?

4

  • 1

    Related post that possibly answers your question: stackoverflow.com/questions/59824884/…

    – CompuChip

    23 hours ago

  • I understand that there are cases where unnamed template parameter can be useful, but I don't understand in this particular case. Why would we need specialization ? Especially with operator+ you can't even pass a template parameter when writing "ym + m"

    – Joseph Perez

    23 hours ago

  • 3

    Candidate for C++ question (and answer) of the week award?

    – Bathsheba

    22 hours ago

  • I still would try to avoid writing auto x = operator+<0>(ym, m);

    – Eljay

    17 hours ago

1 Answer
1


24

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

1

  • 1

    And the reason for the specification to be this way is because adding a multiple of years can be implemented slightly more efficiently than adding months: Just add to the internal year field without touching the month field.

    – Howard Hinnant

    17 hours ago



Leave a Reply

Your email address will not be published. Required fields are marked *