Недавно я начал предпочитать бесплатные функции 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
, содержащего два указателя на 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
), но даже так,действительно ли два приведенных выше случая влекут за собой такие разные затраты? Или я что-то не так делаю?