2016-08-05 6 views
1

私は次のようにクロノ持続時間を使用しようとしていますが、上記のいずれかに比率を増加させると、elapsed -= tickeRateの場合にはerror: no viable overloaded '-='のコンパイル時にエラーが発生します。なぜ小さいクロノ::期間が減算されませんか?

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によって、適切な期間及び ティックカウントにD変換することにより時間を構築::クロノ:: duration_cast(D).count()。

(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 == falsetickRateとは、std::chrono::high_resolution_clock::durationstd::chrono::duration<long int, std::ratio<1l, 1000000000l>>されている間、この場合

は、elapsedのタイプはstd::chrono::duration<long long, std::ratio<1,20>>である(すなわち 持続時間のいずれかが浮動小数点チック使用、または周期2は、正確期間によって 割り切れるです)私のamd64 GCC6.1で。あなたはelapsed-=操作を実行すると

、コンパイラはelapsed自体の同じ型にtickRateを変換しようとします。

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から1つを減算するには、ピリオドがアリコートであることを確認する必要があります。ここで:

elapsed -= tickRate; 

あなたは100 nsであることを起こるstd::chrono::duration<long long, std::ratio_multiply<std::ratio<100,1>,std::nano>>に等しい(少なくともMSVC++ 2015年)であるclock::durationから(秒間隔の1/60である)std::chrono::duration<long long, std::ratio<1,60>>を減算してみてください。

合計すると、1/60 sは、100 nsの整数倍ではありません。

関連する問題