2094. duration conversion overflow shouldn't participate in overload resolution

Section: 23.17.5.1 [time.duration.cons] Status: C++14 Submitter: Vicente J. Botet Escriba Opened: 2011-10-31 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [time.duration.cons].

View all issues with C++14 status.

Discussion:

23.17.5.1 [time.duration.cons] says:

template <class Rep2, class Period2>
  constexpr duration(const duration<Rep2, Period2>& d);

Remarks: This constructor shall not participate in overload resolution unless treat_as_floating_point<rep>::value is true or both ratio_divide<Period2, period>::den is 1 and treat_as_floating_point<Rep2>::value is false.

The evaluation of ratio_divide<Period2, period>::den could make ratio_divide<Period2, period>::num overflow.

This occur for example when we try to create a millisecond (period=ratio<1,1000>) from an exa-second (Period2=ratio<1018>).

ratio_divide<ratio<1018>, ratio<1,1000>>::num is 1021 which overflows which makes the compiler error.

If the function f is overloaded with milliseconds and seconds

void f(milliseconds);
void f(seconds);

The following fails to compile.

duration<int,exa> r(1);
f(r);

While the conversion to seconds work, the conversion to milliseconds make the program fail at compile time. In my opinion, this program should be well formed and the constructor from duration<int,exa> to milliseconds shouldn't participate in overload resolution as the result can not be represented.

I think the wording of the standard can be improved so no misinterpretations are possible by adding that "no overflow is induced by the conversion".

[2012, Kona]

Move to Review.

Pete: The wording is not right.

Howard: Will implement this to be sure it works.

Jeffrey: If ratio needs a new hook, should it be exposed to users for their own uses?

Pete: No.

Move to Review, Howard to implement in a way that mere mortals can understand.

[2013-04-18, Bristol]

Proposed resolution:

This wording is relative to the FDIS.

Change the following paragraphs of 23.17.5.1 [time.duration.cons] p4 indicated:

template <class Rep2, class Period2>
  constexpr duration(const duration<Rep2, Period2>& d);

Remarks: This constructor shall not participate in overload resolution unless no overflow is induced in the conversion and treat_as_floating_point<rep>::value is true or both ratio_divide<Period2, period>::den is 1 and treat_as_floating_point<Rep2>::value is false. [ Note: This requirement prevents implicit truncation error when converting between integral-based duration types. Such a construction could easily lead to confusion about the value of the duration. — end note ]