为什么不能将 `std::chrono::hours` 添加到 `std::chrono::sys_days` 中?

5

使用<chrono>库迈出第一步,我从对天为基础的time_point进行基本算术开始。感谢@HowardHinnant的一个非常有用的帖子,我成功地写出了这个

#include <chrono>
using namespace std::chrono_literals;

int main()
{
    std::chrono::sys_days d {std::chrono::January/31/2022};
    d += std::chrono::days{2}; // ok
    //d += 48h; // error: no match for 'operator+=' with std::chrono::hours
}

我不明白为什么d += 48h;不被允许。在这个表达式中,rvalue是一个std::chrono::hours变量,代表时间间隔,而std::chrono::time_point<>::operator+=接受的是一个duration。这里的理念是什么?按照单位量分不同的duration类型,必须与time_point的粒度兼容吗?为什么?
另一方面,我理解为什么d += 2d;会出现错误,因为在这种情况下,std::literals::chrono_literals::operator""d是一个std::chrono::day,它不是一个duration(尽管这对于构成日期文字很方便,但我觉得有点不一致)。我想知道是否有更方便的方法来表示等价于std::chrono::days{2}的duration文字。

因为 sys_days 的分辨率是天而不是小时,所以超过这个范围的一切都会丢失。如果您想要小时级别的精度,则使用小时,或者更好的方法是直接使用 std::chrono::time_point - user11877195
@Sahsahae 在我的聪明才智中,我假设 48h 是等同于两天的持续时间,因为我无法用 2d 表达它。我选择了一天的粒度来看看它是如何工作的,但似乎我需要更好地研究这个库背后的原理。 - MatG
1
一种更方便的表达时间段字面量等同于 days{2} 的方法——没有人能阻止你创建自己的 operator""_days - Ranoiaetep
@Ranoiaetep 这是一个很好的观点,我之前没有注意到。 - MatG
1
关于时间段、时间点和时钟的基础知识,这里有一个1小时的视频教程:https://www.youtube.com/watch?v=P32hvk8b13M。关于日历和时区如何建立的视频,请参见:https://www.youtube.com/watch?v=adSAN282YIw。 - Howard Hinnant
1个回答

7
你可以将小时添加到天数中,但你不能隐式地将其转换回天数。你需要进行强制类型转换。这里有一个示例
d = std::chrono::time_point_cast<std::chrono::days>(d + 48h);

因此,operator+ 接受 hours,结果是一个以小时为单位的 time_point。我认为 d+=48h; 表达了明确的意图,但现在我看到隐式转换可能会隐藏不良行为。 - MatG
在这种情况下,您将会丢失一个“0”,但通常它是一种有损转换。 - Caleth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接