container::erase и const_iterator
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 03.04.10 12:50
Оценка:
Привет всем.

Сделал для себя маленькое и приятное открытие — в STL из VS2008 basic_string::erase(first,last) оформлен как
iterator __CLR_OR_THIS_CALL erase(const_iterator _First, const_iterator _Last)

Удаление символа, на который указывает итератор:
iterator __CLR_OR_THIS_CALL erase(const_iterator _Where)


У std::vector — сделано аналогично.

И ведь действительно — почему бы и нет? Тем более что это упрощает жизнь в некоторых случаях.

Надо будет такое в собственных контейнерах тоже реализовать

---
А что по этому поводу говорит современный стандарт C++?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: container::erase и const_iterator
От: remark Россия http://www.1024cores.net/
Дата: 03.04.10 12:54
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Сделал для себя маленькое и приятное открытие — в STL из VS2008 basic_string::erase(first,last) оформлен как

КД>
КД>iterator __CLR_OR_THIS_CALL erase(const_iterator _First, const_iterator _Last)
КД>

КД>Удаление символа, на который указывает итератор:
КД>
КД>iterator __CLR_OR_THIS_CALL erase(const_iterator _Where)
КД>


А чего тут неприятного? Сами-то методы неконстантные


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: container::erase и const_iterator
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 03.04.10 13:37
Оценка:
Здравствуйте, remark, Вы писали:

КД>>Сделал для себя маленькое и приятное открытие — в STL из VS2008 basic_string::erase(first,last) оформлен как

КД>>
КД>>iterator __CLR_OR_THIS_CALL erase(const_iterator _First, const_iterator _Last)
КД>>

КД>>Удаление символа, на который указывает итератор:
КД>>
КД>>iterator __CLR_OR_THIS_CALL erase(const_iterator _Where)
КД>>

R>А чего тут неприятного? Сами-то методы неконстантные

В старом STL, из BCB5, используются неконстантные итераторы.

Видать "кто-то" допетрил, что это лишнее
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: container::erase и const_iterator
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 03.04.10 15:05
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>В старом STL, из BCB5, используются неконстантные итераторы.

КД>Видать "кто-то" допетрил, что это лишнее

И кстати, в VS2005 — тоже неконстантные итераторы. Гы.

Как я удачно это дело обнаружил
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: container::erase и const_iterator
От: Roman Odaisky Украина  
Дата: 04.04.10 07:31
Оценка: 6 (1)
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>А что по этому поводу говорит современный стандарт C++?


C++03::21.3.5.5 говорит, что iterator, не const_iterator. В C++0x изменений не обнаружил.
До последнего не верил в пирамиду Лебедева.
Re: container::erase и const_iterator
От: Bell Россия  
Дата: 05.04.10 04:00
Оценка: -1
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>И ведь действительно — почему бы и нет? Тем более что это упрощает жизнь в некоторых случаях.


Что-то я навскидку не вижу преимуществ Метод собираемся вызывать неконстантный, значит под руками неконстантный контейнер, и получить неконстантные итераторы не составляет труда...
Любите книгу — источник знаний (с) М.Горький
Re[2]: container::erase и const_iterator
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.04.10 05:53
Оценка:
Здравствуйте, Bell, Вы писали:

КД>>И ведь действительно — почему бы и нет? Тем более что это упрощает жизнь в некоторых случаях.


B>Что-то я навскидку не вижу преимуществ Метод собираемся вызывать неконстантный, значит под руками неконстантный контейнер, и получить неконстантные итераторы не составляет труда...


1. неконстантный контейнер
2. перебор элементов с использованием алгоритмов, которые требуют константные итераторы по указателю или ссылке
3. на основе результатов этих алгоритмов нужно удалять элементы из контейнера

--- Как результат
1. Перебираем элементы с применением константных итераторов
2. Передаем в erase эти самые констатные итераторы.

--- Конкретный пример
Есть текст запроса: "select .... from .... where column1=:param1 and column2=:param2"
Нужно param1 и param2 заменить на "?": "select .... from .... where column1=? and column2=?"

Есть утилиты, которые делают выборку именованного параметра
bool get_named_param(/*in-out*/const_iterator& beg,/*in*/const_iterator end,/*out*/string& Name)

Ну а дальше — все как я описал в 1-3

Эти утилиты юзаются еще в другом месте, где ничего не меняется — только сканируется изначально константная строка.

Вообще конечно, все эти примеры ... ну да ладно. Можно было работать в 1-3 и с неконстантным итератором. В STL из VS2008 iterator наследует const_iterator, поэтому по ссылке/указателю передается без проблем.

BCB5 (хотя и юзает для итераторов строки голые char*/const char*) тоже без проблем передает "char*" в "const char*&". Но не может передать "char**" в параметр "const char**".

Вообщем, я подумал — надо нечто, что без проблем будет без проблем собираться под разыми STL/комиляторами. И тут я обнаружил то, о чем написал в самом начале. И узрел я спасение от своих терзаний
template<class charT,class traits,class Allocator>
inline typename std::basic_string<charT,traits,Allocator>::iterator
 erase(std::basic_string<charT,traits,Allocator>&                         s,
       typename std::basic_string<charT,traits,Allocator>::const_iterator first,
       typename std::basic_string<charT,traits,Allocator>::const_iterator last)
{
 assert(first<=last);

 assert(s.begin()<=first);
 assert(first<=s.end());

 assert(s.begin()<=last);
 assert(last<=s.end());

#if(__STL_BASIC_STRING_ERASE_USE_CONST_ITERATOR) //1 для STL из VS2008
 return s.erase(first,last);
#else
 return s.erase(s.begin()+(first-s.begin()),
                s.begin()+(last-s.begin()));
#endif
}//erase
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: container::erase и const_iterator
От: uzhas Ниоткуда  
Дата: 05.04.10 05:57
Оценка: 1 (1)
Здравствуйте, Bell, Вы писали:

B>Что-то я навскидку не вижу преимуществ Метод собираемся вызывать неконстантный, значит под руками неконстантный контейнер, и получить неконстантные итераторы не составляет труда...


Иногда бывает по-другому: итераторы получили из константных методов, а потом приходим в неконстантный метод для того, чтобы удалить элементы под этими итераторами, у нас ничего не получается
Re[3]: container::erase и const_iterator
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.04.10 06:09
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Иногда бывает по-другому: итераторы получили из константных методов, а потом приходим в неконстантный метод для того, чтобы удалить элементы под этими итераторами, у нас ничего не получается


Спасибо, что помог сформулировать данную мысль
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: container::erase и const_iterator
От: Юрий Жмеренецкий ICQ 380412032
Дата: 05.04.10 10:38
Оценка: 18 (3)
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Привет всем.


КД>Сделал для себя маленькое и приятное открытие — в STL из VS2008 basic_string::erase(first,last) оформлен как

КД>
КД>iterator __CLR_OR_THIS_CALL erase(const_iterator _First, const_iterator _Last)
КД>

КД>Удаление символа, на который указывает итератор:
КД>
КД>iterator __CLR_OR_THIS_CALL erase(const_iterator _Where)
КД>


КД>У std::vector — сделано аналогично.


КД>И ведь действительно — почему бы и нет? Тем более что это упрощает жизнь в некоторых случаях.


КД>Надо будет такое в собственных контейнерах тоже реализовать


КД>---

КД>А что по этому поводу говорит современный стандарт C++?

N3035:

21.4.6.5/8 basic_string::erase
...
iterator erase(const_iterator first, const_iterator last);


+ N2350: Container insert/erase and iterator constness

+ DR#180: Container member iterator arguments constness has unintended consequences

It is the constness of the container which should control whether it can be modified through a member function such as erase(), not the constness of the iterators. The iterators only serve to give positioning information.

Here's a simple and typical example problem which is currently very difficult or impossible to solve without the change proposed below.

Wrap a standard container C in a class W which allows clients to find and read (but not modify) a subrange of (C.begin(), C.end()]. The only modification clients are allowed to make to elements in this subrange is to erase them from C through the use of a member function of W.
...
Proposed resolution:
...
Update the following signatures in 21.4.6.5 [string::erase]:
iterator erase(const_iterator const_position);
iterator erase(const_iterator first, const_iterator last);
...
The LWG believes that this issue should be considered as part of a general review of const issues for the next revision of the standard.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.