gcc reverse_iterator пропавшие без вести операторов сравнения?

У меня есть проблема с помощью итераторов реверса константы на контейнерах неконстанты с gcc. Ну, только определенные версии gcc.

#include <vector>
#include <iostream>

using namespace std;

int main() {
    const char v0[4] = "abc";
    vector<char> v(v0, v0 + 3);

    // This block works fine
    vector<char>::const_iterator i;
    for (i = v.begin(); i != v.end(); ++i)
        cout << *i;
    cout << endl;

    // This block generates compile error with gcc 3.4.4 and gcc 4.0.1
    vector<char>::const_reverse_iterator r;
    for (r = v.rbegin(); r != v.rend(); ++r)
        cout << *r;
    cout << endl;

    return 0;
}

Эта программа компилирует хорошо и выполнения с gcc 4.2.1 (Leopard Mac) и с Visual Studio 8 и 9 (Windows), и с gcc 4.1.2 (Linux).

Однако существует ошибка компиляции с gcc 3.4.4 (cygwin) и с gcc 4.0.1 (Snow Leopard Mac).

test.cpp:18: error: no match for 'operator!=' in 'r != std::vector<_Tp, _Alloc>::rend() [with _Tp = char, _Alloc = std::allocator<char>]()'

Действительно ли это - ошибка в более ранних версиях gcc?

Из-за других проблем с gcc 4.2.1 на Mac, мы должны использовать gcc 4.0.1 на Mac, таким образом, просто использование более нового компилятора не является идеальным решением для меня. Таким образом, я предполагаю, что должен измениться, как я использую обратные итераторы. Какие-либо предложения?

5
задан Christopher Bruns 25 January 2010 в 19:45
поделиться

4 ответа

Это дефект текущего стандарта: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280

Edit: Немного развивается: Дело в том, что в текущем стандарте:

  • vector::reverse_iterator указан как std::reverse_iterator, а vector::const_reverse_iterator как std::reverse_iterator.
  • Операторы реляций на std::reverse_iterator определены с одним параметром шаблона, что делает reverse_iterator и reverse_iterator несопоставимыми.

В своем коде вы сравниваете const_reverse_iterator с результатом вызова "rend()" по неконстантному вектору, которым является (неконстантный) reverse_iterator.

В C++0x внесены два взаимосвязанных изменения для исправления таких проблем:

  • Реляционные операторы на reverse_iterator теперь берут два шаблонных параметра
  • Контейнеры вроде вектора имеют дополнительные методы для эксплицитного запроса const_iterator: cbegin(), cend(), crbegin() и crend().

В вашем случае обходным путем был бы явный запрос const_reverse_iterator для render():

vector<char>::const_reverse_iterator r;
const vector<char>::const_reverse_iterator crend = v.rend();
for (r = v.rbegin(); r != crend; ++r)
    cout << *r;
10
ответ дан 18 December 2019 в 11:56
поделиться

Поскольку для сравнения итераторы должны быть одного типа, а неконстантный контейнер дает неконстантные итераторы, почему бы не объявить и не инициализировать конечный итератор одновременно.

for (vector<char>::const_reverse_iterator r = v.rbegin(), end_it = v.rend(); r != end_it; ++r)
    cout << *r;

При использовании более старого компилятора это может даже дать небольшое преимущество в производительности.

2
ответ дан 18 December 2019 в 11:56
поделиться

Я прочитал эту страницу с большим интересом. Наша команда разработки использует Apex уже около 2 лет, и я хотел бы подвести итоги нашего опыта.

Для создания основных приложений CRUD APEX действительно отлично. На самом деле я рекомендую попробовать сами. Мы сталкивались с некоторыми первоначальными незначительными трудностями, устанавливающими его, но, похоже, были вытянуты в выпуске 3.2.

Хорошо

  • отлично подходит для простых приложений. Если приложение будет расти в сложности, рассмотрите альтернативное решение.
  • Встроенные шаблоны означают, что ваше приложение выглядит довольно профессионально (хотя некоторые будут обсуждаться этим).
  • Хорошая поддержка форума и сообщества, с большим количеством нетерпеливых людей, чтобы помочь вам.
  • Некоторые превосходные встроенные элементы управления. Любите графики и отчеты (но см. Ниже).

Плохо

  • Отладчик - Abysmal. Если вы использовали Visual Studio (и даже древние версии Microsoft Access), вы будете съеживаться в отладчик. Нет точек останова, отладки сообщений, извергающих на экране в большом списке, на необходимость вручную печатать сообщения отладки на экран. Ужасный. Причина многих, много часов, потерянных для поддержки.

  • Как только ваше приложение станет сложным или требует каких-либо богатых функциональных возможностей, вы должны прибегать к хакам JavaScript и HTML / CSS, которые создают отладку и поддержку еще более сложными (хотя вы можете использовать инструменты, такие как Firebug или Visual Studio, чтобы помочь с это).

  • Мы столкнулись с необъяснимися ошибками состояний сеанса, а таблицы стилей становятся «отделенными» из приложения без объяснения - назвать пару вопросов.

  • Поддержка незнакомых приложений может быть сложной, поскольку может быть трудно следовать за логическим потоком страницы без хорошего отладчика. И я не покупаю акции отклика «скважин - приложения должны быть закодированы лучше». Потому что в реальном мире они не являются - особенно когда вы используете подрядчик.

  • Отчеты выглядят хорошо, но не очень хорошо, если вы не можете распечатать их или экспортировать в PDF. Конечно, вы можете выложить для отчетного сервера, в конце концов мы использовали другое решение.

В целом

Я бы сказал, что все средства используют APEX для простых приложений CruD. За что угодно более легкой сложности идут на .NET или Java. Я бы не привел бы никакого уведомления о статье Wiki на Apex, так как она очень перекошена. Обратите внимание, как «трудно отлаживать» (на мой взгляд, самое большое не удалось) было удалено из статьи.

Что-то, что нужно очень осторожно, а также нелепое утверждение, что вы можете быстро преобразовать базы данных доступа прямо к вершине. Да, это будет работать, если вы получите доступ к БД очень, очень упрощенно. Что-нибудь умеренно сложное, забудь, как мы нашли.

Мы определенно не использовали его для приложений для веб-сигналов, только внутренних. Есть просто слишком много трудностей, делающих вещи, которые вы предприняли как должное, скажем, .NET. Я знаю, что есть такие сайты, такие как asktom, но это не совсем комплекс. Сможем ли мы увидеть следующий Facebook на нем? Я не думаю, что я уверен, что кто-то читает, это будет трещина на этом.

APEX подытоживает в предыдущем комментариев - менеджеры видят демонстрацию, и быстро покупают, убедили, что они нашли серебряную пулю, которая будет сокращена времена развития. У меня были менеджеры, позвонив мне и говорили, нам нужно приложение БД с 40 столами здания в неделю в вершине, пожалуйста - вот как далеко миф совершил миф. Реальность несколько отличается. Да, некоторые вещи быстрее, существенно быстрее, но вы потеряете время в других областях - отладка, поддержка и настройку.

Конечно, вы лучше всего решаете для себя. Установите его, дайте ей, вам может понравиться. Но не обманывайте себя давления быстрого развития до тех пор, пока вы не получите его хорошего для реалистичного применения.

-121--1094323--- 1094323-

Случайные вещи, которые я бы попробую:

отбрасывают возврат от RENK () в Const_Reverse_iterator, чтобы увидеть, будет ли проблема по сравнению с регулярным итератором Const:

r != static_cast<vector<char>::const_reverse_iterator>(v.rend())

, если это не Работа, как насчет изменения r из Const_Reverse_iterator до регулярного обратного итератора.

Нет подсказки, если эти работы, но это то, что я бы попробую в этой ситуации.

2
ответ дан 18 December 2019 в 11:56
поделиться

Это может быть ошибкой в ​​старом вере в GCC, но я думаю, что ошибка в вашем коде - вы не удались # # Включить <итератор> . Вероятно, стоит только смотрите в дальнейшем, если исправить, что не решает проблему.

С другой стороны, если вы используете , как показано на рисунке , как показано (т. Е. Корпус цикла Cout << * R; ) Вы должны просто использовать STD :: Copy :

std::ostream_iterator<char> output(std::cout);

// frontwards
std::copy(v.begin(), v.end(), output);

// backwards
std::copy(v.rbegin(), v.rend(), output);

Также есть Copy_Backwardswardswards , но я не верю, что это сделает то, что вы хотите.

Редактировать: Еще одна возможность рассмотреть возможность рассмотрения: если добавление требуемого заголовка не работает, и вам действительно нужен обратный итератор, вы можете рассмотреть возможность использования STLPORT вместо собственной библиотеки (по крайней мере, для Старые компиляторы).

1
ответ дан 18 December 2019 в 11:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: