5

私は現在、生データの配列またはベクトルを読み取る次の関数を持っています ( _readStreamis a std::ifstream) :

template<typename IteratorType> 
inline bool MyClass::readRawData(
    const IteratorType& first, 
    const IteratorType& last, 
    typename std::iterator_traits<IteratorType>::iterator_category* = nullptr
    )
{
    _readStream.read(reinterpret_cast<char*>(&*first), (last-first)*sizeof(*first));
    return _readStream.good();
}

最初の質問: この機能は大丈夫ですか?

メモリのブロックを直接読み取るため、からのメモリ ブロックがメモリ内で連続しfirstている場合にのみ機能します。lastそれを確認する方法は?

4

3 に答える 3

4

サンプル関数は別として、イテレータが 2 つの間のすべての要素のアドレスをチェックせずに連続したメモリを形成することを完全に確認することはできません。

ただし、合理的な健全性テストは、2 つの間のメモリ領域が 2 つの間のカウントと同じかどうかを確認することです。

assert(&*last - &*first == last - first &&
    "Iterators must represent a contiguous memory region");
于 2012-09-30T03:50:49.247 に答える
3

n4183は、連続したイテレータ トレイトを追加するというアイデアを取り上げた論文です。現在、C++1z (できれば C++17) について検討中です。

その下で、連続したイテレータかstd::is_contiguous_iterator<It>::valueどうかを取得できます。It(これには、イテレータの設計者からのサポートが必要です)。

于 2015-08-12T14:16:42.827 に答える
2
typename std::iterator_traits<IteratorType>::iterator_category* = nullptr

std::iterator_traits無条件に定義された member type を持つプライマリ テンプレートがあるため、これは役に立ちませんiterator_category。テンプレート パラメータはイテレータであり、そうでない場合は前提条件違反であると暗黙のうちに想定されています。そのため、無効なインスタンス化で上記が試行された場合、SFINAE は発生しませんが、ハード エラーが発生します。

メモリ ブロックを直接読み取るため、最初から最後までのメモリ ブロックがメモリ内で連続している場合にのみ機能します。それを確認する方法は?

「メモリ内で連続」の概念にどのような正確な要件を課すかはわかりません。しかし、あなたは次のことを考慮しましたか?

template<typename T>
bool readRawData(T* first, T* last);

[ first, last )配列へのイテレータとしての有効なポインタ範囲であるという前提条件で。

さらに要件を追加したい場合T(たとえば、 を使用しているため、簡単なコピー可能性などread)、それらを表現/文書化することもできます。

于 2012-09-30T03:48:50.213 に答える