将std :: chrono :: duration存储为成员的类?

Bri*_*and 8 c++ c++11 c++-chrono

我想创建一个类,其构造接受一个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);
}
Run Code Online (Sandbox Code Playgroud)

这可能是一个类的成员函数.但是下面这个案子呢?

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??? */
}
Run Code Online (Sandbox Code Playgroud)

是否有一种干净的方法来保持持续时间"抽象"A)理想情况下不将整个班级变成模板化的类,B)将类转换为类模板?

How*_*ant 21

一个更简单的解决方案是使用一个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};
}
Run Code Online (Sandbox Code Playgroud)

除非你真的想要这种普遍性,否则没有必要对所有内容进行模板化.所有预定义单位都隐式转换为nanoseconds.如果您进入客户端发送的内容无法完全转换为的状态nanoseconds,您将在编译时找到,然后您可以决定是否要模板,或者可能使用其他解决方案.

另一种比存储a更好的解决方案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};
}
Run Code Online (Sandbox Code Playgroud)

每个 chrono::duration都会隐式转换为浮点持续时间.在这个例子中,我选择秒作为精度,并选择double作为表示.你可以选择你想要的任何东西(长两倍和几微秒,无论如何).

你在这里有很多选择.所有这些都为您提供了裸露double不会的类型安全性,并且不会牺牲性能和灵活性.

只需使用双倍存储秒

是你能得到的最糟糕的建议. 学习 <chrono>.它具有很大的灵活性,并且有很多不需要模板的东西.


如果坚持要你学习<chrono>而不给你一些指导,那也许是不礼貌的.

Nicolai M. Josuttis的"C++标准库 - 教程和参考,第2版"有一个很好的介绍<chrono>.仅这一章就可以支付这本书的费用.一定要搞定第二版.他的第一版涵盖了C++ 03,但没有<chrono>.披露:我没有安排(财务或其他方面)宣传Nico的书,尽管他是我的朋友.

对于那些愿意深入研究委员会文件的人,<chrono>提案如下:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm

关于duration(在内容中链接)的部分是我建议你开始的地方,如果你不耐烦.它更像是一个教程,而不是技术论文,因为我试图让委员会自己加快速度.它包括我在上面的答案中给出的建议,以及更多.

这是一个视频介绍教程:

https://www.youtube.com/watch?v=P32hvk8b13M


Nat*_*ica 9

我可以看到的一个解决方案是在类中使用特定的持续时间,然后您可以使用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)) { }
Run Code Online (Sandbox Code Playgroud)

  • 我会尽快存储一个实际提到它代表什么而不是双重的类型,这可能是任何东西(ms?秒?).标准类型还可以防止您将秒传递给期望ms的函数,并允许您在它们之间轻松转换.如果你忘记了它们下面是可怕的模板,它们实际上相当不错 (3认同)