2017-02-05 6 views
1

バイナリファイルを読む2つの関数があります。パラメータパック展開の順番

第一の機能は、ファイルからsizeof(T)バイトを読み取ります

template<typename T> 
T read() { ... some IO operations ... }; 

第二の機能は、各テンプレートパラメータで最初のものを複数回呼び出します。

template<typename... Ts> 
std::tuple<Ts...> read_all() { 
    return std::make_tuple(read<Ts>()...); 
}; 

すべてが第一の関数呼び出しのためのを除いて正常に動作します。何か

uint32_t a; 
uint8_t b; 
std::tie(a, b) = read_all<uint32_t, uint8_t>(); 

などのために最初は read<uint8_t>()と呼ばれ、テンプレートパラメータを渡すの順序を逆にして、ファイル内のバイトの順序を台無しもの read<uint32>()後になります。

確かに、私はread_allをテンプレート引数の逆順に呼び出して、最後に正しい順序を得ることができますが、もっと明確な方法がありますか?

答えて

8

C++では、関数の引数が評価される順序は指定されていません。関数への式がすべてストリームからのデータを消費する場合、オブジェクトが間違った順序で読み込まれる動作を取得できます。左から右へ

ブレース初期化子リストは、あなたがより良い結果を得る必要がありますので、しかし、あなたが何かしようとした場合に評価されています。私は心の中でそれを維持します

template<typename... Ts> 
std::tuple<Ts...> read_all() { 
    return std::tuple<Ts...>{read<Ts>()...}; 
} 
1

私は少し単純にそれを維持し、これを行うだろう:

uint32_t a; 
uint8_t b; 
std::tie(a, b) = read<std::tuple<uint32_t, uint8_t>>(); 

この方法では、単一のread()ありますし、あなたはタプル(または構造体)を使用する場合でも、直接フィールドをtie()をスキップすることができます。

+0

を、ありがとう –

関連する問題