Здравствуйте, Erop, Вы писали:
E>Зато в твоём нельзя записать пустую строку, в качестве значения, а в исходном было можно...
И что? Пустую строку в обоих вариантах и в качестве ключа можно записать, это что, нормально? В постановке задачи, которую мы здесь прочитали, не было ничего про то, как обрабатывать особые случаи, и (1) человек написал как написал; (2) я обратил внимание на то, что, во-первых, можно обойтись без промежуточной строки, во-вторых, лучше использовать operator[] для вставления в map; и (3) ты занимаешься ерундой.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Erop, Вы писали:
E>>Зато в твоём нельзя записать пустую строку, в качестве значения, а в исходном было можно...
I>И что? Пустую строку в обоих вариантах и в качестве ключа можно записать, это что, нормально? В постановке задачи, которую мы здесь прочитали, не было ничего про то, как обрабатывать особые случаи, и (1) человек написал как написал; (2) я обратил внимание на то, что, во-первых, можно обойтись без промежуточной строки, во-вторых, лучше использовать operator[] для вставления в map; и (3) ты занимаешься ерундой.
Вообще, я думал, у топикастера вызывает затруднение работа с map, string, ifstream, а не с алгоритмом, поэтому да, написал как написал .
Здравствуйте, igna, Вы писали:
I>(1) человек написал как написал;
Ну код у тебя неэквивалентен коду у него...
Кстати, ни ты ни он не проверяете, что такой ключ уже есть...
Просто как-то не понятно. Если речь идёт о том, как примерно можно написать, то не понятно зачем это "примерно" совершенствовать? А если речь идёт о подробностях реализации, то почему ты считаешь их несущественными тогда?
I>(2) <...> во-вторых, лучше использовать operator[] для вставления в map; и
Почему?
I>(3) ты занимаешься ерундой.
Это т. н. переход на личности? Или ты что-то другое имел в виду?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, igna, Вы писали:
I>>>(2) <...> во-вторых, лучше использовать operator[] для вставления в map; и E>>Почему? I>Из эстетических соображений.
Они, IMHO, субъективны...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, igna, Вы писали:
I>В данном случае operator[] еще и эффективнее, если значения string value длинные настолько, что их хранение приводит к выделению свободной памяти.
Это если строка без COW... К сожалению STL даёт мало гарантий по производительности, так что всё зависит...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Это если строка без COW... К сожалению STL даёт мало гарантий по производительности, так что всё зависит...
Зависит. Тем не менее чаще всего в map именно value "тяжелая" часть, и копировать ее два раза вместо одного IMHO неразумно. Хотя Meyers в Effective STL дает именно такую рекомендацию, при заполнении map (то есть не при обновлении значений, а именно при заполнении) использовать insert, а не operator[]. Последний мол приводит в вызову конструктора по умолчанию для значения. Про то, что при использовании insert вместо конструктора по умолчанию вызывается конструктор копирования, Meyers почему-то не упоминает.
PS. Поставлю оценку super тому, кто разубедит меня и покажет, что Meyers прав.
Майерс таки не прав. Не прав в том смысле, что такая рекомендация не может быть безусловной, поскольку получаются совершенно разные последовательности операций:
map::insert:
передача параметра — конструктор value_type: копирование значения
создание ноды — конструктор копирования value_type: копирование значения
map::operator[] (обычно реализован как find + хинтовый insert):
find — никаких операций со значением
а далее insert — всё что описано выше, только в параметр подставляется значение, сконструированное по умолчанию
ну и потом уже, видимо, присвоение (map[i] = ...)
Итого, для типа значения:
insert: 2 копирования (полноценных)
operator []: конструктор по умолчанию + 2 копирования пустышки + присвоение
Для stl строк скорее всего использование [] будет более эффективным, поскольку операция копирования пустых строк практически бесплатна, а вот полноценное копирование затратно. В то же время, очевидно, что заполнение map<int, int> будет работать быстрее с использованием insert.
Здравствуйте, sokel, Вы писали:
S>Если уж insert, то лучше использовать insert(map_type::value_type(...)), потому как для make_pair получаем уже 3 копирования!
Копирование при возврате из make_pair компилятор вправе оптимизировать.
Здравствуйте, sokel, Вы писали:
I>>Копирование при возврате из make_pair компилятор вправе оптимизировать.
S>Вправе, но не обязан:
Когда программист думает о том, чтобы не писать код, заведомо приводящий к выполнению избыточных действий, это называется избеганием преждевременной пессимизации.
Когда программист заранее, до выявления необходимости оптимизации, думает о том, чтобы не писать код, возможно приводящий к выполнению избыточных действий, это называется преждевременной оптимизацией.
Здравствуйте, igna, Вы писали:
I>Когда программист думает о том, чтобы не писать код, заведомо приводящий к выполнению избыточных действий, это называется избеганием преждевременной пессимизации.
I>Когда программист заранее, до выявления необходимости оптимизации, думает о том, чтобы не писать код, возможно приводящий к выполнению избыточных действий, это называется преждевременной оптимизацией.
А в данном случае это "заведомо" или "возможно"? Или, может, "возможно не приводящий к выполнению избыточных действий".
Я привёл простой пример, в котором три компилятора показали что этот случай ближе к "заведомо". Значит, использование make_pair вместо value_type — это преждевременная пессимизация. Хотя у make_pair есть плюс — проверка типов, тогда как конструктор value_type может использовать скрытую (и, возможно, не предусмотренную) конвертацию.