我正在编写一个代码,在其中计算时间长度,然后将其保存在列表中。
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
但是在代码上方运行时,我得到以下错误:
最有可能出现此错误,因为我有一个没有任何项目的空列表。这就是为什么我想到在第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>
答案 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
。
还请注意,我不使用double
或long 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。