2016-08-05 33 views
1

我正在嘗試按如下方式使用計時持續時間,但如果我將該比率增加爲高於std::ratio<1,50>的任何值,則會在編譯期間引發error: no viable overloaded '-='時發生的錯誤elapsed -= tickeRate爲什麼不會減小chrono :: durations?

int main() 
{ 
    using clock = std::chrono::high_resolution_clock; 
    using seconds = std::chrono::seconds; 

    std::chrono::duration<long long, std::ratio<1,20>> tickRate(1); 
// std::chrono::duration<long long, std::ratio<1,60>> tickRate(1); 

    clock::time_point start, stop; 

    start = clock::now(); 
    std::this_thread::sleep_for(seconds(1)); 
    stop = clock::now(); 

    clock::duration elapsed = stop - start; 

    int i = 0; 
    while (elapsed >= tickRate) 
    { 
     elapsed -= tickRate; 
     i++; 
    } 

    std::cout << "ticked " << i << " times." << std::endl; 

    return 0; 
} 

第一個問題是,爲什麼它只在tickRate> 1/50時拋出錯誤?第二,我可以研究什麼課題,以便我可以通過未來的問題推理?

編輯:

編譯器版本是:蘋果LLVM 7.0.2版(鐺-700.1.81)

此外,該實際工作有更小的數字,但不能肯定它。對我來說,1/51 .. 1/99失敗,但是1/100開始再次正常工作。我嘗試過雙打,並且1/2500,1/3600扔同樣的錯誤。現在我更加困惑。

+0

在我的機器上它可以很好地適用於'100','200'和'1000'。可能這個比例應該可以被一些數字整除。 – alexeykuzmin0

+0

你的編譯器是什麼? – rustyx

+0

似乎是這樣。自從失敗後,我從未超過60歲,但在您說出這一點之後,我嘗試了不同的較小值。我會更新這個問題。謝謝。 – stewsims

回答

3
template< class Rep2, class Period2 > 
constexpr duration(const duration<Rep2,Period2>& d); 
(4) (since C++11) 

通過的std ::計時:: duration_cast(d).Count之間的轉換d爲適當的時間段和 滴答計數,彷彿構造一個持續時間()。 爲了防止在轉換過程中截斷,則此構造 如果沒有溢出由 轉換誘導並僅參與重載解析:

(1)std::chrono::treat_as_floating_point<rep>::value == true

或兩者:

(2)std::ratio_divide<Period2, period>::den == 1 , 和 std::chrono::treat_as_floating_point<Rep2>::value == false。 (即, 任一持續時間使用浮點蜱,或PERIOD2正是 整除週期)

在這種情況下,elapsed類型是std::chrono::duration<long long, std::ratio<1,20>>,而的tickRatestd::chrono::high_resolution_clock::duration,其std::chrono::duration<long int, std::ratio<1l, 1000000000l>>在我的amd64 GCC6.1上。

當您在elapsed上執行-=操作時,編譯器會嘗試將tickRate轉換爲相同類型的elapsed本身。

因爲long long不是浮點類型,所以第2條適用於這種情況。 此轉換僅在您的分母可以整除std::high_resolution_clock::period.den時有效。

+0

儘管你在'elapsed' /'tickRate'上顛倒了類型,這是有道理的。後續問題是 - 處理這個問題的最佳方法是什麼?如果我的編譯器/系統上的時鐘持續時間不可分,但是它在你的上 - 我怎麼能提前知道?我做的測試只是提前'duration_cast (tickRate)',有沒有更好的方法? – stewsims

+0

@stewsims:這裏(http://howardhinnant.github.io/duration_io/chrono_util.html)是一些你可以使用的實用工具,如果你想在非零方向截斷(這是'duration_cast'的作用) 。 –

5

要從另一個duration減去一個,你應該確保他們的週期是等分的。這裏:

elapsed -= tickRate; 

嘗試從clock::duration減去std::chrono::duration<long long, std::ratio<1,60>>(這是在第二時間間隔1/60),其是(至少在MSVC++ 2015)等於std::chrono::duration<long long, std::ratio_multiply<std::ratio<100,1>,std::nano>>這恰好是100 ns

總結起來,這裏的問題是1/60 s不是整數倍的間隔100 ns

相關問題