![](/img/trans.png)
[英]Precision of std::chrono::duration<double> and double - C++
[英]How to declare a std::chrono::duration<double> variable in c++
我正在編寫一個代碼,在其中計算時間長度,然后將其保存在列表中。
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>
可能您不應該使用列表在索引處存儲數據。 嘗試改用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()
)范圍已排序。
您正在嘗試寫入結束迭代器。 當列表為空時, 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.
}
沒有合適的構造函數可用於將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的單位,表示納秒。
工作代碼在這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.