This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
chrono::duration constructorSection: 30.5.2 [time.duration.cons], 30.5.6 [time.duration.nonmember] Status: C++20 Submitter: Barry Revzin Opened: 2018-01-22 Last modified: 2021-02-25
Priority: 3
View all other issues in [time.duration.cons].
View all issues with C++20 status.
Discussion:
The converting constructor in std::chrono::duration is currently specified as
(30.5.2 [time.duration.cons] p1):
template<class Rep2> constexpr explicit duration(const Rep2& r);Remarks: This constructor shall not participate in overload resolution unless
Rep2is implicitly convertible torepand […]
But the parameter is of type Rep2 const, so we should check that Rep2 const is
implicitly convertible to rep, not just Rep2. This means that for a type like:
struct X { operator int64_t() /* not const */; };
std::is_constructible_v<std::chrono::seconds, X> is true, but actual
construction will fail to compile.
[2018-06 Rapperswil Thursday issues processing]
P3; Status to Open
[2018-11 San Diego Thursday night issue processing]
Jonathan to provide updated wording; the underlying text has changed.
[2018-12-05 Jonathan provides new wording]
In San Diego Geoff noticed that the current WP does not use CR.
Jonathan provides new wording consistent with the
editorial changes
that removed CR.
Previous resolution [SUPERSEDED]:This wording is relative to N4713.
Modify 30.5.2 [time.duration.cons] as indicated:
template<class Rep2> constexpr explicit duration(const Rep2& r);-1- Remarks: This constructor shall not participate in overload resolution unless
is_convertible_v<const Rep2&, rep>istrueandRep2is implicitly convertible torep[…] -2- Effects: Constructs an object of type
(1.1) —
treat_as_floating_point_v<rep>istrueor(1.2) —
treat_as_floating_point_v<Rep2>isfalse.duration. -3- Postconditions:count() == static_cast<rep>(r).Modify 30.5.6 [time.duration.nonmember] as indicated:
template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const duration<Rep1, Period>& d, const Rep2& s);-4- Remarks: This operator shall not participate in overload resolution unless
[…]is_convertible_v<const Rep2&, CR(Rep1, Rep2)>istrue.Rep2is implicitly convertible toCR(Rep1, Rep2)template<class Rep1, class Rep2, class Period> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const Rep1& s, const duration<Rep2, Period>& d);-6- Remarks: This operator shall not participate in overload resolution unless
[…]is_convertible_v<const Rep1&, CR(Rep1, Rep2)>istrue.Rep1is implicitly convertible toCR(Rep1, Rep2)template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator/(const duration<Rep1, Period>& d, const Rep2& s);[…]-8- Remarks: This operator shall not participate in overload resolution unless
is_convertible_v<const Rep2&, CR(Rep1, Rep2)>istrueandRep2is implicitly convertible toCR(Rep1, Rep2)Rep2is not a specialization ofduration.template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator%(const duration<Rep1, Period>& d, const Rep2& s);-11- Remarks: This operator shall not participate in overload resolution unless
[…]is_convertible_v<const Rep2&, CR(Rep1, Rep2)>istrueandRep2is implicitly convertible toCR(Rep1, Rep2)Rep2is not a specialization ofduration.
This wording is relative to N4791.
Modify 30.5.2 [time.duration.cons] as indicated:
template<class Rep2> constexpr explicit duration(const Rep2& r);-1- Remarks: This constructor shall not participate in overload resolution unless
is_convertible_v<const Rep2&, rep>istrueandRep2is implicitly convertible torep[…] -2- Effects: Constructs an object of type
(1.1) —
treat_as_floating_point_v<rep>istrueor(1.2) —
treat_as_floating_point_v<Rep2>isfalse.duration. -3- Postconditions:count() == static_cast<rep>(r).Modify 30.5.6 [time.duration.nonmember] as indicated:
template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const duration<Rep1, Period>& d, const Rep2& s);-4- Remarks: This operator shall not participate in overload resolution unless
[…]is_convertible_v<const Rep2&, common_type_t<Rep1, Rep2>>istrue.Rep2is implicitly convertible tocommon_type_t<Rep1, Rep2>template<class Rep1, class Rep2, class Period> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const Rep1& s, const duration<Rep2, Period>& d);-6- Remarks: This operator shall not participate in overload resolution unless
[…]is_convertible_v<const Rep1&, common_type_t<Rep1, Rep2>>istrue.Rep1is implicitly convertible tocommon_type_t<Rep1, Rep2>template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator/(const duration<Rep1, Period>& d, const Rep2& s);[…]-8- Remarks: This operator shall not participate in overload resolution unless
is_convertible_v<const Rep2&, common_type_t<Rep1, Rep2>>istrueandRep2is implicitly convertible tocommon_type_t<Rep1, Rep2>Rep2is not a specialization ofduration.template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator%(const duration<Rep1, Period>& d, const Rep2& s);-11- Remarks: This operator shall not participate in overload resolution unless
[…]is_convertible_v<const Rep2&, common_type_t<Rep1, Rep2>>istrueandRep2is implicitly convertible tocommon_type_t<Rep1, Rep2>Rep2is not a specialization ofduration.
[2020-02-13, Prague]
Rebase to most recent working draft
[2020-02 Status to Immediate on Thursday night in Prague.]
Proposed resolution:
This wording is relative to N4849.
Modify 30.5.2 [time.duration.cons] as indicated:
template<class Rep2> constexpr explicit duration(const Rep2& r);-1- Constraints:
is_convertible_v<const Rep2&, rep>istrueand[…] -2- Postconditions:
(1.1) —
treat_as_floating_point_v<rep>istrueor(1.2) —
treat_as_floating_point_v<Rep2>isfalse.count() == static_cast<rep>(r).
Modify 30.5.6 [time.duration.nonmember] as indicated:
template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const duration<Rep1, Period>& d, const Rep2& s);-4- Constraints:
[…]is_convertible_v<const Rep2&, common_type_t<Rep1, Rep2>>istrue.template<class Rep1, class Rep2, class Period> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const Rep1& s, const duration<Rep2, Period>& d);-6- Constraints:
[…]is_convertible_v<const Rep1&, common_type_t<Rep1, Rep2>>istrue.template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator/(const duration<Rep1, Period>& d, const Rep2& s);[…]-8- Constraints:
is_convertible_v<const Rep2&, common_type_t<Rep1, Rep2>>istrueandRep2is not a specialization ofduration.template<class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator%(const duration<Rep1, Period>& d, const Rep2& s);-12- Constraints:
[…]is_convertible_v<const Rep2&, common_type_t<Rep1, Rep2>>istrueandRep2is not a specialization ofduration.