接受std::chrono::任何表示/周期的持续时间

Accepting std::chrono::duration of any representation/period

本文关键字:周期 持续时间 任何 std chrono 接受 表示      更新时间:2023-10-16

我希望函数接受对调用者有意义的任何单位的持续时间。

例如:

transition->after(chrono::seconds(3));
transition->after(chrono::milliseconds(500));
transition->after(chrono::hours(1));

这个after函数的有效签名是什么样子的?我能避免使它成为模板化函数吗?

有几个常见的选项

1)使用模板。这样做的优点是不需要转换,但需要使用模板,而这可能是不可能的。例如,如果这是一个虚函数的接口

template<typename Rep, typename Period>
void after( std::chrono::duration< Rep, Period > t);

2)使用整数表示,以及接口所需的最低周期。例如,如果您的函数实际上只需要纳秒,那么可以直接使用它。如果不发生精度损失,这将隐式地转换为纳秒。您可以使用预定义的周期来指定其他周期,或者显式地将其指定为持续时间

的一部分。
void after( std::chrono::nanoseconds t) ;

3)使用双重表示,如果精度不是问题,但接受所有输入的能力是问题,这可能是有用的。这将隐式地转换任何持续时间,因为所有周期都允许转换为浮点类型。例如,如果想要双精度秒数,可以使用

void after( std::chrono::duration< double > t);

从c++17开始,我们可以使用std::variant

void after(std::variant<std::chrono::minutes, std::chrono::seconds> dt)

after函数中,您可以使用std::visit来避免代码重复。在下面的示例中,我们将给定的持续时间添加到"3秒":

void after(std::variant<std::chrono::minutes, std::chrono::seconds> dt) {
    std::chrono::seconds secs{3};
    std::visit([&secs](auto v)
                   { secs += v; }, dt);
}