Здравствуйте, Mazay, Вы писали:
M>Понадобилось отсортировать контейнер, в котором доступ к элементам осуществляется по индексу. (Борладновский TStrings) M>Взялся было за std::sort(), но быстро понял, что RandomAccessIterator'ов у меня нету. В принципе написать адаптер не сложно, но есть подозрение что не я первый и такой велосипед уже существует. M>Если у вас есть такой адаптер/обёртка — поделитесь пожалуйста. Можно ткнуть носом в какой-нить boost::* или std::*.
Mazay wrote:
>> > Пробовал. Только swap при таком раскладе на совсем правильно работает. >> > Если при присваивании этих объектов (назовём их IterRef) делать >> > копирование того на что они ссылаются (строк в TStrings tstrings), то >> > при свопе одно значение теряется. Если при их присваивании копировать > kan>Э... почему теряются?.. Надо не копировать, а переставлять значения > в TStrings, на которые ссылается IterRef > А как переставлять? swap это делает через временную переменную и > оператор присваивания. (tmp = a, a = b, b = tmp; )
IterRef можно сделать так, что если он никуда не зааттачен (создан пустым конструктором), то хранит данные внутри себя.
Тогда, вроде, такой своп заработает. Сам не пробовал, код набирал прямо тут.
>> > собственно ссылки (ну для данной "ссылки" копировать поля tstrings и i), >> > то смысла в таком свопе очень мало. Получается что собственно строки не >> > копируются. Конечно можно самому напистаь swap для таких "ссылок", но я >> > думаю это не последняя функция где возникнут подобные проблеммы. > > kan>Дубовый способ — создать std::vector индексов (вектор длиной > TStrings::Size, содержимое — числа > kan>0..(TStrings::Size()-1)), отсортировать его (сравнивая индексируемые > значения), потом переставить содержимое TStrings в > kan>соответствие с этим вектором. > В крайнем случае я могу просто реализовать sort для TStrings. Весь > огород затевался ради того чтоб бесшовно использовать TStrings с > алгоритмами STL вообще. Похоже всё упирается в то, что из TStrings > нельзя получить ссылку на его элемент. (Борладны — чёртовы > велосипедисты. рррррр. Или это ещё один минус STL в копилку соседнего > топика — почему я не могу отсортировать контейнер для которого просто > определён operator[] ? Хотя в защиту STL надо заметить, что там не
Потому что operator[] это по сути тоже самое, что и *iter, а значит у тебя были бы те же проблемы.
> совсем честный оператор — это борландовое изобретение — property с индексом)
Тогда это камень в огород багланда — ввели изобретение, а до ума не довели.
> Главное гармония ...
Эт-точно!
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Mazay, Вы писали:
...
Видимо, TStrings::operator[] возвращает AnsiString по значению В этом случае копирование должно быть достаточно эффективным, и, возможно, в качестве решения подойдет такой способ:
создаем vector AnsiString-ов из объекта TStrings
сортируем вектор с помощью std::sort
копируем вектор обратно.
Здравствуйте, Mazay, Вы писали:
kan>>>А если ... сделать объект, с операторами "operator=(const Element&e){tstrings.set(i, e);}" и "Element& kan>>>operator(){return tstrings.get(i);}"?
RO>>...то это не будет Random Access Iterator. Стандарт не позволяет итераторы со ссылками-прокси.
M>А вообще (если забыть про итераторы) существует ли какая-то разумная реализация такого прокси?
Ну, если забыть про итераторы, то можно забыть и о std::sort. По поводу прокси — наверное, boost::reference_wrapper (aka Boost.Ref) может помочь.
Здравствуйте, Mazay, Вы писали:
M>Понадобилось отсортировать контейнер, в котором доступ к элементам осуществляется по индексу. (Борладновский TStrings) M>Взялся было за std::sort(), но быстро понял, что RandomAccessIterator'ов у меня нету. В принципе написать адаптер не сложно, но есть подозрение что не я первый и такой велосипед уже существует. M>Если у вас есть такой адаптер/обёртка — поделитесь пожалуйста. Можно ткнуть носом в какой-нить boost::* или std::*.
Если есть гарантия, что TString хранит строку в непрерывном блоке, то итераторы можно получить так:
TString str;
...
TChar* first = &str[0];
TChar* last = first + str.GetLength();
std::sort(first, last);
Понадобилось отсортировать контейнер, в котором доступ к элементам осуществляется по индексу. (Борладновский TStrings)
Взялся было за std::sort(), но быстро понял, что RandomAccessIterator'ов у меня нету. В принципе написать адаптер не сложно, но есть подозрение что не я первый и такой велосипед уже существует.
Если у вас есть такой адаптер/обёртка — поделитесь пожалуйста. Можно ткнуть носом в какой-нить boost::* или std::*.
Главное гармония ...
Re: Сделать итератор из оператора []
От:
Аноним
Дата:
07.09.06 07:45
Оценка:
Здравствуйте, Mazay, Вы писали:
M>Понадобилось отсортировать контейнер, в котором доступ к элементам осуществляется по индексу. (Борладновский TStrings) M>Взялся было за std::sort(), но быстро понял, что RandomAccessIterator'ов у меня нету. В принципе написать адаптер не сложно, но есть подозрение что не я первый и такой велосипед уже существует. M>Если у вас есть такой адаптер/обёртка — поделитесь пожалуйста. Можно ткнуть носом в какой-нить boost::* или std::*.
TStrings это базовый класс. В TStringList есть свойство Sorted.
А>TStrings это базовый класс. В TStringList есть свойство Sorted.
Спасибо за информацию. Но,к сожалению, в моём случае есть только указатель на TStrings. Можно конечно попробовать кастануть, но мне такой вариант не очень нравится.
Спасибо. То что надо. Но мне уже не поможет. Поскольку для использования этого шаблона я должен уметь делать так: node_base& dereference() const;
А я не могу вернуть ссылку на элемемнт контейнера . Могу только get(i)/set(i). Сейчас пытаюсь сочинить над этими аксессорами како-нибудь прокси. Но что-то всё печально получется. Такое чувство, что в плюсах этого в принципе не сделать
Mazay wrote:
> K>http://boost.org/libs/iterator/doc/iterator_facade.html#tutorial-example > > Спасибо. То что надо. Но мне уже не поможет. Поскольку для использования > этого шаблона я должен уметь делать так: node_base& dereference() const; > А я не могу вернуть ссылку на элемемнт контейнера . Могу только > get(i)/set(i). Сейчас пытаюсь сочинить над этими аксессорами како-нибудь > прокси. Но что-то всё печально получется. Такое чувство, что в плюсах > этого в принципе не сделать
А если этой node_base сделать объект, с операторами "operator=(const Element&e){tstrings.set(i, e);}" и "Element&
operator(){return tstrings.get(i);}"?
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, kan, Вы писали:
kan>Mazay wrote:
>> K>http://boost.org/libs/iterator/doc/iterator_facade.html#tutorial-example >> >> Спасибо. То что надо. Но мне уже не поможет. Поскольку для использования >> этого шаблона я должен уметь делать так: node_base& dereference() const; >> А я не могу вернуть ссылку на элемемнт контейнера . Могу только >> get(i)/set(i). Сейчас пытаюсь сочинить над этими аксессорами како-нибудь >> прокси. Но что-то всё печально получется. Такое чувство, что в плюсах >> этого в принципе не сделать kan>А если этой node_base сделать объект, с операторами "operator=(const Element&e){tstrings.set(i, e);}" и "Element& kan>operator(){return tstrings.get(i);}"?
Пробовал. Только swap при таком раскладе на совсем правильно работает. Если при присваивании этих объектов (назовём их IterRef) делать копирование того на что они ссылаются (строк в TStrings tstrings), то при свопе одно значение теряется. Если при их присваивании копировать собственно ссылки (ну для данной "ссылки" копировать поля tstrings и i), то смысла в таком свопе очень мало. Получается что собственно строки не копируются. Конечно можно самому напистаь swap для таких "ссылок", но я думаю это не последняя функция где возникнут подобные проблеммы.
Mazay wrote:
> Пробовал. Только swap при таком раскладе на совсем правильно работает. > Если при присваивании этих объектов (назовём их IterRef) делать > копирование того на что они ссылаются (строк в TStrings tstrings), то > при свопе одно значение теряется. Если при их присваивании копировать
Э... почему теряются?.. Надо не копировать, а переставлять значения в TStrings, на которые ссылается IterRef
> собственно ссылки (ну для данной "ссылки" копировать поля tstrings и i), > то смысла в таком свопе очень мало. Получается что собственно строки не > копируются. Конечно можно самому напистаь swap для таких "ссылок", но я > думаю это не последняя функция где возникнут подобные проблеммы.
Дубовый способ — создать std::vector индексов (вектор длиной TStrings::Size, содержимое — числа
0..(TStrings::Size()-1)), отсортировать его (сравнивая индексируемые значения), потом переставить содержимое TStrings в
соответствие с этим вектором.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, kan, Вы писали:
kan>Mazay wrote:
>> Пробовал. Только swap при таком раскладе на совсем правильно работает. >> Если при присваивании этих объектов (назовём их IterRef) делать >> копирование того на что они ссылаются (строк в TStrings tstrings), то >> при свопе одно значение теряется. Если при их присваивании копировать kan>Э... почему теряются?.. Надо не копировать, а переставлять значения в TStrings, на которые ссылается IterRef
А как переставлять? swap это делает через временную переменную и оператор присваивания. (tmp = a, a = b, b = tmp; )
>> собственно ссылки (ну для данной "ссылки" копировать поля tstrings и i), >> то смысла в таком свопе очень мало. Получается что собственно строки не >> копируются. Конечно можно самому напистаь swap для таких "ссылок", но я >> думаю это не последняя функция где возникнут подобные проблеммы.
kan>Дубовый способ — создать std::vector индексов (вектор длиной TStrings::Size, содержимое — числа kan>0..(TStrings::Size()-1)), отсортировать его (сравнивая индексируемые значения), потом переставить содержимое TStrings в kan>соответствие с этим вектором.
В крайнем случае я могу просто реализовать sort для TStrings. Весь огород затевался ради того чтоб бесшовно использовать TStrings с алгоритмами STL вообще. Похоже всё упирается в то, что из TStrings нельзя получить ссылку на его элемент. (Борладны — чёртовы велосипедисты. рррррр. Или это ещё один минус STL в копилку соседнего топика — почему я не могу отсортировать контейнер для которого просто определён operator[] ? Хотя в защиту STL надо заметить, что там не совсем честный оператор — это борландовое изобретение — property с индексом)
Здравствуйте, kan, Вы писали:
kan>А если ... сделать объект, с операторами "operator=(const Element&e){tstrings.set(i, e);}" и "Element& kan>operator(){return tstrings.get(i);}"?
...то это не будет Random Access Iterator. Стандарт не позволяет итераторы со ссылками-прокси.
вовсе не приводит к изменению первого элемента strs. Зато приводит к AV. То что оказывается в указателе first указывает в никуда. А вот такой код срабатывает как и ожидается:
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, kan, Вы писали:
kan>>А если ... сделать объект, с операторами "operator=(const Element&e){tstrings.set(i, e);}" и "Element& kan>>operator(){return tstrings.get(i);}"?
RO>...то это не будет Random Access Iterator. Стандарт не позволяет итераторы со ссылками-прокси.
А вообще (если забыть про итераторы) существует ли какая-то разумная реализация такого прокси?
Roman Odaisky wrote:
> kan>А если ... сделать объект, с операторами "operator=(const > Element&e){tstrings.set(i, e);}" и "Element& > kan>operator(){return tstrings.get(i);}"? > > ...то это не будет Random Access Iterator. Стандарт не позволяет > итераторы со ссылками-прокси.
Этот объект не итератор, а результат разыменования итератора.
Или я что-то не понял?
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Mazay, Вы писали:
M>Понадобилось отсортировать контейнер, в котором доступ к элементам осуществляется по индексу. (Борладновский TStrings) M>Взялся было за std::sort(), но быстро понял, что RandomAccessIterator'ов у меня нету. В принципе написать адаптер не сложно, но есть подозрение что не я первый и такой велосипед уже существует. M>Если у вас есть такой адаптер/обёртка — поделитесь пожалуйста. Можно ткнуть носом в какой-нить boost::* или std::*.
Что-то такое сваял
Конечно, заранее неизвестно, как отнесется мистический борландский компилятор (какой, кстати?) к коду, расположенному ниже, но на vc 7.1 на std::sort все работает достаточно стабильно:
Здравствуйте, Mazay, Вы писали:
M>Понадобилось отсортировать контейнер, в котором доступ к элементам осуществляется по индексу. (Борладновский TStrings) M>Взялся было за std::sort(), но быстро понял, что RandomAccessIterator'ов у меня нету. В принципе написать адаптер не сложно, но есть подозрение что не я первый и такой велосипед уже существует. M>Если у вас есть такой адаптер/обёртка — поделитесь пожалуйста. Можно ткнуть носом в какой-нить boost::* или std::*.