This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
chrono::local_time
should be constrainedSection: 30.7.9 [time.clock.local] Status: New Submitter: Jonathan Wakely Opened: 2025-05-16 Last modified: 2025-05-16
Priority: Not Prioritized
View all issues with New status.
Discussion:
Stream insertion for chrono::local_time
is defined in terms of conversion to
chrono::sys_time
, but not all chrono::sys_time
specializations
can be inserted into an ostream, because one of the overloads is
constrained and the other requires convertibility to chrono::sys_days
(see 30.7.2.3 [time.clock.system.nonmembers]).
This means the following code fails to compile:
#include <iostream>
#include <chrono>
template<typename T>
concept ostream_insertable = requires (std::ostream& o, const T& t) { o << t; };
using D = std::chrono::duration<double>;
int main() {
if constexpr (ostream_insertable<std::chrono::sys_time<D>>)
std::cout << std::chrono::sys_time<D>{};
if constexpr (ostream_insertable<std::chrono::local_time<D>>)
std::cout << std::chrono::local_time<D>{}; // FAIL
}
The first condition is false, because there's no overload that's suitable.
The second is true, because the operator<<
overload for
chrono::local_time
isn't constrained and so insertion appears to be valid.
But actually trying to use it is ill-formed, because it tries to convert the
local_time<D>
to a sys_time<D>
and then insert that, which isn't valid.
Proposed resolution:
This wording is relative to N5008.
Modify 30.7.9 [time.clock.local] as indicated:
template<class charT, class traits, class Duration> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& lt);
-?- Constraints:
os << sys_time<Duration>{lt.time_since_epoch()}
is a valid expression.-2- Effects:
os << sys_time<Duration>{lt.time_since_epoch()};
-3- Returns:
os
.