1

Boost.Rangeを使用して、いくつかのデータとこのデータのコンテナークラスを渡します。データは別のスレッドにロードされ、場合によってはまだ準備ができていない可能性があります。この場合、コンテナはデフォルトのiterator_rangeで初期化されるため、単一のイテレータが含まれます。データコンテナの割り当てとコピーを行っています(したがって、iterator_ranges)。ただし、iterator_rangeコピーコンストラクターはbegin()とend()を呼び出し、オリジナルが特異である場合にアサートします。そのため、空のデータコンテナをコピーすることはできません。

この制限を回避する方法はありますか?

この制限が実装されているのはなぜですか?以下は問題なく動作しますが、範囲は同じように動作するべきではありませんか?

typedef std::vector<int>::iterator iterator;
iterator it; // Singular
iterator it2 = it; // Works

boost::iterator_range<iterator> range; // Singular
boost::iterator_range<iterator> range2 = range; // Asserts in debug, but why?
4

1 に答える 1

3

「機能する」とは、「現在のコンパイラバージョンと呼び出しオプションでは機能しない」という意味の場合、そうです。単一のイテレータを割り当てると「機能する」可能性があります。実際、コード

typedef std::vector<int>::iterator iterator;
iterator it; // Singular
iterator it2 = it; // Works

結果として未定義の動作が発生するため、何が起こるかについてはコンパイラの気まぐれに任されています。

C ++標準には、それについて次のように書かれています(セクション[lib.iterator.requirements] / 5):

[...]ほとんどの式の結果は、特異値に対して未定義です。唯一の例外は、特異値を保持するイテレータへの非特異値の割り当てです。この場合、特異値は他の値と同じ方法で上書きされます。参照解除可能な値と過去の値は常に非特異です。

したがって、最終範囲では、単一のイテレータと同様に機能します。それはあなたが望むようには機能しません。
最良の方法は、データの準備ができていないときに、特異な範囲ではなく、空の範囲(非特異なイテレーターで明示的に構築されたもの)を使用することだと思います。

于 2010-09-06T11:35:31.177 に答える