The following bit of code used to compile ok with g++ 9.2.1. #include <date.h> int main() { std::istringstream str{"2020-04-30 17:30:00.000"}; std::chrono::local_time<std::chrono::milliseconds> loc_time; str >> date::parse("%Y-%m-%d %H:%M:%S", loc_time); return 0; } (NOTE: date.h is Howard Hinnant's sample implementation of the calendar library included in C++20.) However, when I compile with g++ 10.0.1 using this command line: g++ -c -g -m64 -O3 -Wall -Werror -I/usr/local/include -std=c++2a dt.cpp The compile fails with the following messages (excerpt only/incomplete): dt.cpp:7:50: error: no matching function for call to ‘parse(const char [18], std::chrono::local_time<std::chrono::duration<long int, std::ratio<1, 1000> > >&)’ 7 | str >> date::parse("%Y-%m-%d %H:%M:%S", loc_time); | ^ In file included from dt.cpp:1: /usr/local/include/date.h:7827:1: note: candidate: ‘template<class Parsable, class CharT, class Traits, class Alloc> decltype ((date::from_stream(declval<std::basic_istream<_CharT, _Traits>&>(), format.c_str(), tp), date::parse_manip<Parsable, CharT, Traits, Alloc>{format, tp})) date::parse(const std::__cxx11::basic_string<CharT, Traits, Alloc>&, Parsable&)’ 7827 | parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp) | ^~~~~ /usr/local/include/date.h:7827:1: note: template argument deduction/substitution failed: dt.cpp:7:50: note: mismatched types ‘const std::__cxx11::basic_string<CharT, Traits, Alloc>’ and ‘const char [18]’ 7 | str >> date::parse("%Y-%m-%d %H:%M:%S", loc_time); | ^ In file included from dt.cpp:1: /usr/local/include/date.h:7838:1: note: candidate: ‘template<class Parsable, class CharT, class Traits, class Alloc> decltype ((date::from_stream(declval<std::basic_istream<_CharT, _Traits>&>(), format.c_str(), tp, (& abbrev)), date::parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, (& abbrev)})) date::parse(const std::__cxx11::basic_string<CharT, Traits, Alloc>&, Parsable&, std::__cxx11::basic_string<CharT, Traits, Alloc>&)’ 7838 | parse(const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp, | ^~~~~ /usr/local/include/date.h:7838:1: note: template argument deduction/substitution failed: dt.cpp:7:50: note: mismatched types ‘const std::__cxx11::basic_string<CharT, Traits, Alloc>’ and ‘const char [18]’ 7 | str >> date::parse("%Y-%m-%d %H:%M:%S", loc_time); FYI, I will also notify Howard Hinnant of this issue because he might have a clue as to the cause of the problem.
Can you provide a complete testcase? I'm sure date.h does not include any STL bits. That is, please provide preprocessed source.
It includes tons of std::lib headers: #include <cassert> #include <algorithm> #include <cctype> #include <chrono> #include <climits> #if !(__cplusplus >= 201402) # include <cmath> #endif #include <cstddef> #include <cstdint> #include <cstdlib> #include <ctime> #include <ios> #include <istream> #include <iterator> #include <limits> #include <locale> #include <memory> #include <ostream> #include <ratio> #include <sstream> #include <stdexcept> #include <string> #if HAS_STRING_VIEW # include <string_view> #endif #include <utility> #include <type_traits>
(In reply to Leo Carreon from comment #0) > The following bit of code used to compile ok with g++ 9.2.1. Are you sure? With 9.2 or 9.3 I get: date.cc: In function 'int main()': date.cc:6:18: error: 'local_time' is not a member of 'std::chrono'; did you mean 'date::local_time'? 6 | std::chrono::local_time<std::chrono::milliseconds> loc_time; | ^~~~~~~~~~ In file included from date.cc:1: /home/jwakely/src/date/include/date/date.h:201:11: note: 'date::local_time' declared here 201 | using local_time = std::chrono::time_point<local_t, Duration>; | ^~~~~~~~~~ date.cc:6:54: error: expected primary-expression before '>' token 6 | std::chrono::local_time<std::chrono::milliseconds> loc_time; | ^ date.cc:6:56: error: 'loc_time' was not declared in this scope; did you mean 'localtime'? 6 | std::chrono::local_time<std::chrono::milliseconds> loc_time; | ^~~~~~~~ | localtime
std::local_time is new for GCC 10, so I would not expect the code to compile with odler versions. I would also not expect std::chrono::local_time to work with date::parse because date::parse probably only knows about date::local_t and not std::chrono::local_t.
If I change your code to use date::local_time (as suggested by GCC 9) then it compiles as expected with any recent version of GCC.
Thanks for your comments. I have realized what the issue is. It is to do with local_time and local_days being defined in namespace date and std::chrono.
That doesn't explain why you claim the code worked with GCC 9. I'm going to assume this was user error, as I don't see a bug in libstdc++.
My code was checking the value of __cpp_lib_chrono for the value when calendars and timezones are introduced. When its below this value, it maps namespace date to namespace std::chrono. Now I realize that this is not advisable because you are starting to partially implement the feature which caused the conflict. The lesson learned from this is I have to change my strategy of using sample imlementations of a feature. I'm closing this bug report.
OK thanks for confirming that. N.B. this is why you're supposed to provide preprocessed source. The code you showed to demonstrate the bug did *not* demonstrate it, because you were actually using something different (a modified version of <date.h>, or some extra code not shown in your example). Opening namespace std to add your own declarations to it (such as using-declarations of ::date::local_time) is forbidden, resulting in undefined behaviour. The result you got here is a good example of why. Instead of trying to add things to namespace std, you should do something like: #include <chrono> #if __cpp_lib_chrono >= 201803L namespace time = std::chrono; #else #include <date/date.h> namespace time = date; #endif // use time::duration, time::local_time etc.