[解決済み] C++ std::chrono::time_point を long に変換して戻すには?
質問
を変換する必要があります。
std::chrono::time_point
から
long
型(64ビット整数)に変換します。私は
std::chrono
...
以下は私のコードです。
int main ()
{
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
auto epoch = now.time_since_epoch();
auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
long duration = value.count();
std::chrono::duration<long> dur(duration);
std::chrono::time_point<std::chrono::system_clock> dt(dur);
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
このコードはコンパイルされますが、成功を示しません。
なぜ
dt
とは異なり
now
とは違うのですか?
そのコードには何が欠けているのでしょうか?
どのように解決するのですか?
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
これは
auto
:
auto now = std::chrono::system_clock::now();
でトラフィックしたいので
millisecond
の精度でトラフィックしたいので、先に進んで
time_point
:
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
now_ms
は
time_point
に基づいています。
system_clock
の精度で、しかし
milliseconds
の精度ではなく
system_clock
が持つ精度ではなく
auto epoch = now_ms.time_since_epoch();
epoch
は、現在、タイプ
std::chrono::milliseconds
. そして、この次の文は本質的にno-opになります(単にコピーを作成し、変換を行いません)。
auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
ここで
long duration = value.count();
あなたのコードでも私のコードでも
duration
の数を保持します。
milliseconds
のエポックから
system_clock
.
これ
std::chrono::duration<long> dur(duration);
を作成します。
duration
で表される
long
であり、精度は
seconds
. これは事実上
reinterpret_cast
は
milliseconds
で開催された
value
に
seconds
. これはロジックエラーです。 正しいコードは次のようになります。
std::chrono::milliseconds dur(duration);
この行は
std::chrono::time_point<std::chrono::system_clock> dt(dur);
は
time_point
に基づいて
system_clock
に精度を保持する機能を持つ。
system_clock
のネイティブ精度(通常はミリ秒より細かい)を保持する機能を持つ。 しかし、実行時の値は、ミリ秒の整数値が保持されていることを正しく反映します。
dur
).
修正しても、このテストは(ほぼ)失敗しますが。
if (dt != now)
なぜなら
dt
には整数個の
milliseconds
を保持するが
now
よりも細かい刻みの整数倍を保持します。
millisecond
(よりも細かい刻みを保持します(例えば
microseconds
または
nanoseconds
). したがって、ごくまれに
system_clock::now()
が整数を返した場合のみ
milliseconds
が返ってくれば、テストは合格です。
しかし、代わりに
if (dt != now_ms)
そして、これで期待通りの結果を確実に得ることができます。
すべてをまとめると
int main ()
{
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto value = now_ms.time_since_epoch();
long duration = value.count();
std::chrono::milliseconds dur(duration);
std::chrono::time_point<std::chrono::system_clock> dt(dur);
if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
個人的には、すべての
std::chrono
は冗長すぎると思うので、私ならこうコーディングします。
int main ()
{
using namespace std::chrono;
auto now = system_clock::now();
auto now_ms = time_point_cast<milliseconds>(now);
auto value = now_ms.time_since_epoch();
long duration = value.count();
milliseconds dur(duration);
time_point<system_clock> dt(dur);
if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
どちらが確実に出力されるかというと
Success.
最後に、テンポラリを排除して
time_point
と積分型の間で変換するコードを最小にするために、テンポラリをなくすことをお勧めします。 これらの変換は危険なので、素の積分型を操作するコードを書くのは少なければ少ないほどよいのです。
int main ()
{
using namespace std::chrono;
// Get current time with precision of milliseconds
auto now = time_point_cast<milliseconds>(system_clock::now());
// sys_milliseconds is type time_point<system_clock, milliseconds>
using sys_milliseconds = decltype(now);
// Convert time_point to signed integral type
auto integral_duration = now.time_since_epoch().count();
// Convert signed integral type to time_point
sys_milliseconds dt{milliseconds{integral_duration}};
// test
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
上記の主な危険は
ではなく
を解釈することです。
integral_duration
として
milliseconds
に戻る途中
time_point
. そのリスクを軽減する方法として考えられるのは、「書く」ことです。
sys_milliseconds dt{sys_milliseconds::duration{integral_duration}};
これにより、リスクを減らすことができます。
sys_milliseconds
を使うようにするだけです。
もう一つ例を挙げましょう。 例えば、次のような持続時間を表す積分に変換したいとします。
system_clock
がサポートする時間 (マイクロ秒、10
th
というように、マイクロ秒やナノ秒を指定することができます。) そうすれば、上記のようなミリ秒の指定に悩まされることはない。 コードは次のように単純化されます。
int main ()
{
using namespace std::chrono;
// Get current time with native precision
auto now = system_clock::now();
// Convert time_point to signed integral type
auto integral_duration = now.time_since_epoch().count();
// Convert signed integral type to time_point
system_clock::time_point dt{system_clock::duration{integral_duration}};
// test
if (dt != now)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
}
これはうまくいきますが、もし半分の変換(out to integral)をあるプラットフォームで、残りの半分(in from integral)を別のプラットフォームで実行した場合、以下のようなリスクがあります。
system_clock::duration
は 2 つの変換で異なる精度を持つというリスクを伴います。
関連
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] std::string を const char* または char* に変換する方法
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] std::stringのインスタンスを小文字に変換する方法
-
[解決済み] std::move()とは何ですか?また、どのような場合に使用するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較