Этот код отображает разные выходные данные для разных версий компилятора gcc.
#include "date.h"
#include <iostream>
#include <chrono>
#include <string>
#include <set>
#include <ranges>
#include <algorithm>
using namespace date;
using namespace std;
using namespace std::chrono;
using time_point_t = std::chrono::sys_time<std::chrono::microseconds>;
time_point_t parse_tp(std::string s) {
time_point_t tp;
std::istringstream in(s);
in >> parse("%Y%m%d-%T", tp);
return tp;
}
int
main()
{
auto tp = parse_tp("20240304-13:00:00.002");
std::set<time_point_t> s = {tp, tp + std::chrono::seconds(1)};
std::cout << *std::ranges::lower_bound(s, tp + std::chrono::seconds(1));
}
Чем отличается результат?
Это ошибка?
Спасибо за ваш ответ. Да, но, используя тот же код, я ожидал того же результата..
Все еще расследуем. Но я думаю, что транковая версия может вызывать std::chrono::parse
вместо date::parse
. Пока не уверен.
Да, вот и все @HowardHinnant - мне немного странно, что, анализируя микросекунды вручную, а затем добавляя эту продолжительность к моменту времени, я получаю гораздо лучшие результаты - даже если не округлять до ближайшей миллисекунды, а оставаться на проанализированных микросекундах.
Еще одно (а может и нет) интересное наблюдение: godbolt.org/z/cbsGYWxcq. clang (транк) с результатами libc++ согласуется с gcc 13/clang 17.
Я не думаю, что llvm еще реализует std::chrono::parse
, так что это будет вызов date::parse
.
Уместен ли здесь set
? Разве это не запутанный способ сделать std::cout << (tp + 1s);
? А что самое интересное, tp
сам по себе уже отличается?
Я не считаю, что set
уместно. Я провел тестирование, просто транслируя tp
.
Версия gcc-13 вызывает date::parse
, а версия gcc-trunk вызывает std::chrono::parse
. Они должны делать то же самое, но являются независимыми реализациями.
Вчера я подал https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114244, который находится в этой области, но может повлиять или не повлиять на этот конкретный пример.
См. комментарий ниже от Теда Люнгмо, где вы найдете хорошее объяснение такого поведения.
Причина, по которой ствол не выбирает date::parse
, заключается в неоднозначности выбора date::from_stream
перегрузки, которую можно обойти, используя вместо этого его напрямую date::from_stream(in, "%Y%m%d-%T", tp);
.
Кстати, тот же результат здесь: godbolt.org/z/89Mh4zd5a