алгоритмы STL
От: qaz77  
Дата: 22.03.12 17:03
Оценка:
Вразумите, как можно алгоритмом stl выполнить действие над контейнером с модифицирующим доступом к элементам.
Т.е. что-то вроде этого:
void trim(std::string& str);

void foo()
{
  std::vector<std::string> v;
  //...
  for (std::vector<std::string>::iterator it = v.begin(); it != v.end(); ++it)
  {
    trim(*it);
  }
}

Получается ровно реализация std::for_each, но для него запрещена модификация элемента.
Кто-нибудь знает из каких соображений?

std::transform для такой задачи не очень мне нравится, т.к. привносит копирование элемента:
  std::string trim2(const std::string& str);
  
  void bar()
  {
    std::vector<std::string> v;
    //...
    std::transform(v.begin(), v.end(), v.begin(), trim2);
  }


И еще, связанный вопрос про std::set.
Почему оставлена возможность изменить элемент set'а? Это для компаратора по части элемента?
Если в простом примере поменять элемент, то контейнер умирает:
  std::set<std::string> s;
  s.insert("A")
  s.insert("B");

  *s.begin() = "C";
  //... oops

Если бы разыменование итератора возвращало константную ссылку, то такой проблемы бы не возникало.
При этом не константный итератор позволял бы удалять и вставлять элементы.
В общем, как с ключом в std::map.
Т.е. правильно ли я понимаю, что в map элемент явно разделяется на ключ и нагрузку,
а в set элемент не рассматривается как неизменный ключ?
Re: алгоритмы STL
От: Vain Россия google.ru
Дата: 22.03.12 17:33
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>И еще, связанный вопрос про std::set.

Q>Почему оставлена возможность изменить элемент set'а? Это для компаратора по части элемента?
Q>Если в простом примере поменять элемент, то контейнер умирает:
Q>
Q>  std::set<std::string> s;
Q>  s.insert("A")
Q>  s.insert("B");

Q>  *s.begin() = "C";
Q>  //... oops
Q>

Q>Если бы разыменование итератора возвращало константную ссылку, то такой проблемы бы не возникало.
А если изменения ключа не приводит к изменению порядка, то зачем платить больше?

Q>При этом не константный итератор позволял бы удалять и вставлять элементы.

У вставки/удаления сложность не константная.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: алгоритмы STL
От: zaufi Земля  
Дата: 22.03.12 17:37
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Вразумите, как можно алгоритмом stl выполнить действие над контейнером с модифицирующим доступом к элементам.

<skip>
Q>Получается ровно реализация std::for_each, но для него запрещена модификация элемента.
Q>Кто-нибудь знает из каких соображений?

кривая реализация STL!?
возможность можифицировать элементы во время for_eachопределяется типом итератора: const не-const...

Q>И еще, связанный вопрос про std::set.

Q>Почему оставлена возможность изменить элемент set'а? Это для компаратора по части элемента?

изменение элемента в set'e может привести к необходимости изменить порядок элементов -- поэтому set::iterator по факту тоже самое что и set::const_iterator
(об этом разумеется пишут авторы книжек про С++\STL)

Q>Если в простом примере поменять элемент, то контейнер умирает:

Q>
Q>  std::set<std::string> s;
Q>  s.insert("A")
Q>  s.insert("B");

Q>  *s.begin() = "C";
Q>  //... oops
Q>


вообще говоря это не должно компилиться!
если у тебя это не так, значит твой STL или компилятор
вот что сказал мой gcc 4.6.2 на твой пример:
error: passing 'const std::basic_string<char>' as 'this' argument of 'std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]' discards qualifiers [-fpermissive]


Q>В общем, как с ключом в std::map.

Q>Т.е. правильно ли я понимаю, что в map элемент явно разделяется на ключ и нагрузку,
Q>а в set элемент не рассматривается как неизменный ключ?

да
Re[2]: алгоритмы STL
От: qaz77  
Дата: 22.03.12 17:54
Оценка:
Здравствуйте, Vain, Вы писали:

Q>>Если бы разыменование итератора возвращало константную ссылку, то такой проблемы бы не возникало.

V>А если изменения ключа не приводит к изменению порядка, то зачем платить больше?
Тут все в компайл тайм. Чего платить-то?
А вот в ногу выстрелить шанса меньше. Как с it->first в std::map.

Q>>При этом не константный итератор позволял бы удалять и вставлять элементы.

V>У вставки/удаления сложность не константная.
Это-то здесь причем.
Я имею в виду, что у iterator операторы * и -> возвращали бы константную ссылку, как у const_iterator.
При этом, для iterator можно было бы звать erase и т.п., как обычно.
Re: алгоритмы STL
От: Valen  
Дата: 22.03.12 18:12
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Вразумите, как можно алгоритмом stl выполнить действие над контейнером с модифицирующим доступом к элементам.

Q>Т.е. что-то вроде этого:
Q>
Q>void trim(std::string& str);

Q>void foo()
Q>{
Q>  std::vector<std::string> v;
Q>  //...
Q>  for (std::vector<std::string>::iterator it = v.begin(); it != v.end(); ++it)
Q>  {
Q>    trim(*it);
Q>  }
Q>}
Q>

Q>Получается ровно реализация std::for_each, но для него запрещена модификация элемента.
Q>Кто-нибудь знает из каких соображений?

Стесняюсь показаться ламером, но http://ideone.com/wo9Z6

http://msdn.microsoft.com/en-us/library/e5sk9w9k.aspx

The algorithm for_each is very flexible, allowing the modification of each element within a range in different, user-specified ways.

Re[2]: алгоритмы STL
От: qaz77  
Дата: 22.03.12 18:19
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>возможность можифицировать элементы во время for_eachопределяется типом итератора: const не-const...

Да, что-то я туплю. C std::for_each можно менять элементы.
Смутила фраза в старом MSDN:
template<class InIt, class Fun>
    Fun for_each(InIt first, InIt last, Fun f);

The template function evaluates f(*(first + N)) once for each N in the range [0, last - first).
It then returns f. The call f(*(first + N)) must not alter *(first + N).


Z>изменение элемента в set'e может привести к необходимости изменить порядок элементов -- поэтому set::iterator по факту тоже самое что и set::const_iterator

Z>(об этом разумеется пишут авторы книжек про С++\STL)
Ну не совсем то же. const_iterator в erase и т.п. не пойдет...

Z>вообще говоря это не должно компилиться!

Z>если у тебя это не так, значит твой STL или компилятор
VS 2008
Re[2]: алгоритмы STL
От: qaz77  
Дата: 22.03.12 18:24
Оценка:
Здравствуйте, Valen, Вы писали:

V>Стесняюсь показаться ламером, но http://ideone.com/wo9Z6

Вы правы, меня подвел косяк в старой майкрософтовской доке
Re[3]: алгоритмы STL
От: Vain Россия google.ru
Дата: 22.03.12 19:38
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>>>Если бы разыменование итератора возвращало константную ссылку, то такой проблемы бы не возникало.

V>>А если изменения ключа не приводит к изменению порядка, то зачем платить больше?
Q>Тут все в компайл тайм. Чего платить-то?
Q>А вот в ногу выстрелить шанса меньше. Как с it->first в std::map.
Потому-что изменения ключа не обязательно ломает внутренние структуры, это вообще-то зависит от реализации.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: алгоритмы STL
От: TAL_Shadow  
Дата: 22.03.12 21:18
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Здравствуйте, Valen, Вы писали:


V>>Стесняюсь показаться ламером, но http://ideone.com/wo9Z6

Q>Вы правы, меня подвел косяк в старой майкрософтовской доке

Учитывая это
Автор: TAL_Shadow
Дата: 27.10.11
боюсь она вас не подвела....
Re[4]: алгоритмы STL
От: TAL_Shadow  
Дата: 23.03.12 06:33
Оценка:
Здравствуйте, TAL_Shadow, Вы писали:

TAL>Учитывая это
Автор: TAL_Shadow
Дата: 27.10.11
боюсь она вас не подвела....

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