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
Rep2
is implicitly convertible torep
and […]
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>
istrue
andRep2
is implicitly convertible torep
[…] -2- Effects: Constructs an object of type
(1.1) —
treat_as_floating_point_v<rep>
istrue
or(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
.Rep2
is 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
.Rep1
is 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)>
istrue
andRep2
is implicitly convertible toCR(Rep1, Rep2)
Rep2
is 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)>
istrue
andRep2
is implicitly convertible toCR(Rep1, Rep2)
Rep2
is 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>
istrue
andRep2
is implicitly convertible torep
[…] -2- Effects: Constructs an object of type
(1.1) —
treat_as_floating_point_v<rep>
istrue
or(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
.Rep2
is 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
.Rep1
is 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>>
istrue
andRep2
is implicitly convertible tocommon_type_t<Rep1, Rep2>
Rep2
is 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>>
istrue
andRep2
is implicitly convertible tocommon_type_t<Rep1, Rep2>
Rep2
is 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>
istrue
and[…] -2- Postconditions:
(1.1) —
treat_as_floating_point_v<rep>
istrue
or(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>>
istrue
andRep2
is 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>>
istrue
andRep2
is not a specialization ofduration
.