如何在C ++中声明std :: chrono :: duration <double>变量

时间:2019-05-23 12:36:40

标签: c++ list time chrono

我正在编写一个代码,在其中计算时间长度,然后将其保存在列表中。

auto start_time = std::chrono::high_resolution_clock::now();
/*
 *some code here
*/
auto finish_time = std::chrono::high_resolution_clock::now();

std::chrono::duration<double> time_duration = finish_time - start_time ;

现在,我需要将time_duration保存在给定索引的列表中。如果给定的索引已经包含一个值,则需要将time_duration与该索引的当前值相加并保存。为此,我有以下列表和代码:

list <std::chrono::duration<double>> dTimeList;

auto iter = dTimeList.begin();
advance(iter, 0);  
*iter+= time_duration; //Error at this line

但是在代码上方运行时,我得到以下错误:

enter image description here

最有可能出现此错误,因为我有一个没有任何项目的空列表。这就是为什么我想到在第0个索引处添加一个项目,如下所示:

auto itr = dTimeList.begin();
advance(itr, 0);
std::chrono::duration<double> t = 0.0;
dTimeList.insert(itr, t);

但以上再次也给出了以下错误。我该如何解决此问题。谢谢

No suitable constructor available to convert double to std::chrono::duration<double>

3 个答案:

答案 0 :(得分:2)

可能您不应该使用列表在索引处存储数据。尝试改用std::unordered_map

#include <unordered_map>
auto start_time = std::chrono::high_resolution_clock::now();
/*
 *some code here
*/
auto finish_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> time_duration = finish_time - start_time ;

typedef int YourObjectIdType;

std::unordered_map<YourObjectIdType, std::chrono::duration<double>> dTimes;

,现在插入或更新如下项目:

dTimes[objectId] += time_duration;

或类似这样:

 auto it = dTimes.find(objectId);
 if (it != dTimes.end()) {
      *it += time_duration;
 } else {
      dTimes.insert(std::make_pair(objectId, time_duration));
 }

此外,您可以以相同的方式使用std::map,但速度稍慢,但是[begin()end())范围已排序。

答案 1 :(得分:1)

您正在尝试写入结束迭代器。列表为空时,dTimeList.begin() == dTimeList.end(),因此您无法对其进行写操作。

您需要检查索引是否首先存在,否则请扩展列表:

void add_time_to_list(
    std::list<std::chrono::duration<double>>& l,
    const std::chrono::duration<double>& t,
    std::size_t index = 0
) {
    if (index < l.size()) {
        *std::next(l.begin(), index) += t;
    } else if (index == l.size()) {
        // New element; add to back
        l.push_back(t);
    } else {
        // Here you can throw an error that index is too big
        // or append 0 until it gets to the desired size or something
    }
}

请注意,像这样访问任意索引可能意味着您不需要std::list。使用std::vector*std::next(l.begin(), index)变成l[index])会更容易。我还建议使用std::map,该函数可以编写为:

void add_time_to_list(
    std::map<std::size_t, std::chrono::duration<double>>& m,
    const std::chrono::duration<double>& t,
    std::size_t index = 0
) {
    m[index] += t;  // if m[index] doesn't exist, it is default constructed. 
}

答案 2 :(得分:1)

  

没有合适的构造函数可将double转换为std :: chrono :: duration

我敢建议在这里处理std :: list并不是一个核心问题。

处理std::chrono时,应该了解它的基本概念。对于此处未解释的内容,请在cppreference.com上查找

第一步。您确定需要/想要使用哪个时钟。

using Clock = typename std::chrono::high_resolution_clock ;

第二步。您使用其中声明的持续时间嵌套类型。在您的用例中,您希望有一个持续时间序列。

using time_durations_sequence_type = std::vector<Clock::duration> ;

类型命名非常重要。我故意使用通用术语“序列”。您可能会推动std :: list的想法来实现它,但我看不出为什么。因此,我在上面使用std::vector

还请注意,我不使用doublelong int作为“持续时间”类型。首先,std::duration是“事件发生所花费的时间”。其次,它不是标量,而是类类型。传统上,从C年开始,时间概念仅基于刻度。

因此,为了简而言之,我们使用std :: duration概念,具体化为我们在此处选择使用的“时钟”中的嵌套类型。

   // not a point in time
   Clock::duration
   //
   // there is no guarantee above 
   // is the same type as
   // std::chrono::duration<double>
   // and we do not need one

以上是我们实现您所需功能的全部步骤。

     // two points in time
     auto start_time = Clock::now();
     auto finish_time = Clock::now();

      // the duration
      Clock::duration time_duration = finish_time - start_time ;

现在,我们将持续时间存储在序列类型中。

      time_durations_sequence_type tdst{ time_duration } ;

在其他地方,我们使用累积的存储时间序列。

//  time_durations_sequence_type tdst
for (auto duration : tdst ) {
        std::cout << std::endl 
           << duration.count() << " nano seconds" 
           << std::endl;
}

请注意,上面我们是如何使用count()方法到达实际刻度的,默认情况下,它是std :: chrono的单位为纳秒。

工作代码为here