我想创建一个类,其构造采用std::chrono::duration
参数并将结果存储在成员中,以便稍后将其传递给std::this_thread::sleep_for()
。
我知道我可以编写一些像sleep_for
一样的函数模板,如下所示:
template <typename Rep, typename Period>
void mySleep( std::chrono::duration<Rep, Period> time )
{
std::this_thread::sleep_for(time);
}
这可能是一个类的成员函数。但是下面的案例呢?
class UsesDuration
{
public:
template <typename Rep, typename Period>
UsesDuration( std::chrono::duration<Rep, Period> dur ) :
my_duration(dur) { }
void doSomethingPeriodic()
{
while( some_condition )
{
std::this_thread::sleep_for(my_duration);
somethingInteresting();
}
}
private:
??? my_duration; /* How do I declare this??? */
}
是否有一种干净的方法来保持持续时间“抽象”A)理想情况下不将整个班级变成模板化的班级,B)将班级变成班级模板?
答案 0 :(得分:19)
更简单的解决方案是使用一个比您想要的更好或更精细的std::chrono::duration
:
#include <chrono>
#include <thread>
class UsesDuration
{
public:
UsesDuration( std::chrono::nanoseconds dur ) :
my_duration(dur) { }
void doSomethingPeriodic()
{
while( some_condition )
{
std::this_thread::sleep_for(my_duration);
somethingInteresting();
}
}
void somethingInteresting();
private:
std::chrono::nanoseconds my_duration;
};
int
main()
{
using namespace std::chrono_literals;
UsesDuration x{5min};
}
除非您确实想要这种普遍性,否则无需对所有内容进行模板化。所有预定义单位都隐式转换为nanoseconds
。如果你进入一个客户端发送的东西不会完全转换为nanoseconds
的状态,你会发现在编译时,然后< / em>您可以决定是否要模板,或者可以选择其他解决方案。
另一个比存储double
更好的解决方案是存储一个基于双倍的持续时间:
#include <chrono>
#include <thread>
class UsesDuration
{
public:
UsesDuration( std::chrono::duration<double> dur ) :
my_duration(dur) { }
void doSomethingPeriodic()
{
while( some_condition )
{
std::this_thread::sleep_for(my_duration);
somethingInteresting();
}
}
void somethingInteresting();
private:
std::chrono::duration<double> my_duration;
};
int
main()
{
using namespace std::chrono_literals;
UsesDuration x{5min};
}
每个 chrono::duration
都会隐式转换为浮点持续时间。在这个例子中,我选择秒作为精度,并选择双倍作为表示。你可以选择你想要的任何东西(长两倍和几微秒,无论如何)。
这里有很多选择。而且所有这些都为您提供了类型安全性,只有double
才能赢得,并且不会牺牲性能和灵活性。
只需使用双倍存储秒数
是你能得到的最糟糕的建议。 学习 <chrono>
。它具有很大的灵活性,并且有很多不需要模板的东西。
我坚持要你学习<chrono>
而不给你一些指示,这可能是不礼貌的。
Nicolai M. Josuttis' "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"对<chrono>
有一个很好的介绍。仅这一章就可以支付这本书的费用。一定要搞定第二版。他的第一版涵盖了C ++ 03,它没有<chrono>
。披露:我没有安排(财务或其他方面)推销Nico的书,尽管他是我的朋友。
对于那些愿意深入研究委员会文件的人来说,<chrono>
提案就在这里:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm
关于duration
的部分(链接在内容中)是我建议你开始的地方,如果你不耐烦。它更像是一个教程,而不是技术论文,因为我试图让委员会自己加快速度。它包括我在上面的答案中给出的建议,以及更多。
这是一个视频介绍教程:
答案 1 :(得分:8)
我可以看到的一个解决方案是在您的类中使用特定的持续时间,然后您可以使用std::chrono::duration_cast
从提供给构造函数的类型转换为您用作类成员的类型。这允许您不对模板进行模板设计,但仍然可以使用任何类型的持续时间
template <typename Rep, typename Period>
UsesDuration( std::chrono::duration<Rep, Period> dur ) :
my_duration(std::chrono::duration_cast<decltype(my_duration)>(dur)) { }