私は最近、無料の関数を好み、イテレータを明示的にコピーおよびインクリメント/デクリメントすることを好むようになりましstd::next
たstd::prev
。現在、非常に特殊なケースで奇妙な動作が見られます。それをわかりやすく説明する助けをいただければ幸いです。
boost::any_range
一部の で動作する補間/補外関数がありX_type
ます。範囲型の完全な定義は次のとおりです。
boost::any_range <
const X_type,
boost::random_access_traversal_tag,
const X_type,
std::ptrdiff_t
>
はany_range
、この特定のケースでは、iterator_range
保持する 2 つのポインタからに割り当てられます。これは、 の領域の約半分のビューconst X_type
として機能します。X_type
data()
vector<char>
MSVC 2010 でアプリケーションをコンパイルすると、すべて正常に動作します。MinGW g++ 4.7.0 で同じコードをコンパイルすると、ある特定の場所でハングしているように見えました。
// Previously ensured conditions:
// 1) xrange is nonempty;
// 2) yrange is the same size as xrange.
auto x_equal_or_greater =
std::lower_bound(std::begin(xrange),std::end(xrange),xval);
if (x_equal_or_greater == std::end(xrange))
{
return *yit_from_xit(std::prev(x_equal_or_greater),xrange,yrange);
}
gdb のコードをステップ実行すると、単一のstd::prev
呼び出しから戻るのに非常に長い時間がかかっただけで、動けなくなっていないことがわかりました。libstdc++ ではstd::advance
、最終的には+=
演算子の観点から実装されています。
return
行を次のように置き換えるだけです。
auto xprev=x_equal_or_greater;
--xprev;
return *yit_from_xit(xprev,xrange,yrange);
パフォーマンスは再び素晴らしく、実質的に遅延はありません。
型が消去されたイテレータ ( のイテレータ) を使用することのオーバーヘッドは認識していますany_range
が、それでも、上記の 2 つのケースは実際にそのような異なるコストを負担することになっていますか? それとも私は何か間違ったことをしていますか?