При завершении программы std::map записывается в файл, из которого этот же std::map заполняется при повторном запуске программы. Что вы используете для заполнения, map::insert или map::operator[]?
I>При завершении программы std::map записывается в файл, из которого этот же std::map заполняется при повторном запуске программы. Что вы используете для заполнения, map::insert или map::operator[]?
смотря что мне нужно — безусловное заполнение указанными значениями или с проверкой на существование
если пофиг — использую insert как потенциально более шустрый
Как много веселых ребят, и все делают велосипед...
Здравствуйте, igna, Вы писали:
I>При завершении программы std::map записывается в файл, из которого этот же std::map заполняется при повторном запуске программы. Что вы используете для заполнения, map::insert или map::operator[]?
По крайней мере некоторые распространенные реализации используют тот же самый insert + make_pair в реализации map::operator[]. А поскольку по условию дубликаты в файле отсутствуют, то логичнее сразу же использовать insert — элементы вставляются всегда, "холостых" вызовов make_pair нет.
I>>При завершении программы std::map записывается в файл, из которого этот же std::map заполняется при повторном запуске программы. Что вы используете для заполнения, map::insert или map::operator[]? B>По крайней мере некоторые распространенные реализации используют тот же самый insert + make_pair в реализации map::operator[]. А поскольку по условию дубликаты в файле отсутствуют, то логичнее сразу же использовать insert — элементы вставляются всегда, "холостых" вызовов make_pair нет.
map::operator[] возвращает ссылку на уже вставленный (конструктором по умолчанию) объект которому потом присваивается (second.operator=) нужное значение
map::insert вставляет элемент созданный конструктором копирования из указанного, что потенциально быстрее чем создавать объект с дефолтовым конструктором и потом присваивать ему значение
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
O>map::insert вставляет элемент созданный конструктором копирования из указанного, что потенциально быстрее чем создавать объект с дефолтовым конструктором и потом присваивать ему значение
Верно, но это не только потенциально быстрее, но и потенциально медленнее, поскольку первый элемент вставляемой пары копируется всегда, в то время как при использовании map::operator[] реализация STL может обойтись без этого копирования.
Здравствуйте, Bell, Вы писали:
B>По крайней мере некоторые распространенные реализации используют тот же самый insert + make_pair в реализации map::operator[]. А поскольку по условию дубликаты в файле отсутствуют, то логичнее сразу же использовать insert — элементы вставляются всегда, "холостых" вызовов make_pair нет.
И все же использование map::insert вместо map:operator[]заставляет реализацию STL лишний раз копировать ключ.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, ononim, Вы писали:
O>>map::insert вставляет элемент созданный конструктором копирования из указанного, что потенциально быстрее чем создавать объект с дефолтовым конструктором и потом присваивать ему значение
I>Верно, но это не только потенциально быстрее, но и потенциально медленнее, поскольку первый элемент вставляемой пары копируется всегда, в то время как при использовании map::operator[] реализация STL может обойтись без этого копирования.
Согласен, STLPOrt5, например, использует оптимизированную версию. Более того, к минусам варианта с insert можно добавить то, что make_pair принимает аргументы и возвращает результат по значению. Насколько такое копирование критично — зависит от задачи. Если учесть, что в данном случае мы читаем из файла — относительный проигрыш из-за копирований очень сильно зависит от задачи ).
Здравствуйте, Bell, Вы писали:
B>Более того, к минусам варианта с insert можно добавить то, что make_pair принимает аргументы и возвращает результат по значению.
Кстати, не знаешь, аргументы-то почему по-значению?
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Bell, Вы писали:
B>>Более того, к минусам варианта с insert можно добавить то, что make_pair принимает аргументы и возвращает результат по значению.
I>Кстати, не знаешь, аргументы-то почему по-значению?
Возможно, чтобы избежать проблем с появлением "ссылки на ссылку"
Здравствуйте, Bell, Вы писали:
B>По крайней мере некоторые распространенные реализации используют тот же самый insert + make_pair в реализации map::operator[].
Видимо это было давно — иначе откуда я об этом помню?
В STLPort5 и в DinkumSTL для VC7.1 map::operator[] реализован без использования make_pair...
Здравствуйте, Bell, Вы писали:
B>Видимо это было давно — иначе откуда я об этом помню? B>В STLPort5 и в DinkumSTL для VC7.1 map::operator[] реализован без использования make_pair...
В VC9 тем не менее сначала конструируется map::value_type, затем при вставлении копируется в node, после чего сконструированное значение уничтожается. То есть избавились от make_pair, но избыточное копирование оставили.
mapped_type& operator[](const key_type& _Keyval)
{ // find element matching _Keyval or insert with default mapped
iterator _Where = this->lower_bound(_Keyval);
if (_Where == this->end()
|| this->comp(_Keyval, this->_Key(_Where._Mynode())))
_Where = this->insert(_Where,
value_type(_Keyval, mapped_type()));
return ((*_Where).second);
}
};
Здравствуйте, igna, Вы писали:
I>В VC9 тем не менее сначала конструируется map::value_type, затем при вставлении копируется в node, после чего сконструированное значение уничтожается. То есть избавились от make_pair, но избыточное копирование оставили.
I>
Здравствуйте, igna, Вы писали:
I>При завершении программы std::map записывается в файл, из которого этот же std::map заполняется при повторном запуске программы. Что вы используете для заполнения, map::insert или map::operator[]?
boost::serialization
Одним махом всю мапу сохраняет и загружает*. При бинарной сериализации работает быстро.
Здравствуйте, TimurSPB, Вы писали:
TSP>boost::serialization
Честно говоря мне не задачу нужно решить, просто попался на глаза Скотт-Мейерсовский "Совет 24. Тщательно выбирайте между map::operator[] и map::insert", который (совет) в общем случае неверен.
Здравствуйте, igna, Вы писали:
I>При завершении программы std::map записывается в файл, из которого этот же std::map заполняется при повторном запуске программы. Что вы используете для заполнения, map::insert или map::operator[]?
insert в цикле с результатом предыдущего insert в качестве хинта
Здравствуйте, Alexander G, Вы писали:
AG>insert в цикле с результатом предыдущего insert в качестве хинта
Ответ правильный, вопрос неправильный. То есть задачу я сформулировал не так, как собственно хотел. А хотел я сравнить именно map::operator[] и map::insert как это делается у Скотта Мейерса в "Совет 24. Тщательно выбирайте между map::operator[] и map::insert". Ну ладно, как сформулировано — так сформулировано, и при этой формулировке я скорее всего вообще не использовал бы insert, а написал бы итератор читающий файл и инициализировал бы map парой итераторов.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Bell, Вы писали:
B>>Более того, к минусам варианта с insert можно добавить то, что make_pair принимает аргументы и возвращает результат по значению.
I>Кстати, не знаешь, аргументы-то почему по-значению?
Library Defect Report #181
Discussion:
The claim has surfaced in Usenet that expressions such as
make_pair("abc", 3)
are illegal, notwithstanding their use in examples, because template instantiation tries to bind the first template parameter to const char (&)[4], which type is uncopyable.
I doubt anyone intended that behavior...
Proposed resolution:
In 20.2 [utility], paragraph 1 change the following declaration of make_pair():
template <class T1, class T2> pair<T1,T2> make_pair(const T1&, const T2&);
to:
template <class T1, class T2> pair<T1,T2> make_pair(T1, T2);
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Здравствуйте, igna, Вы писали:
I>>Здравствуйте, Bell, Вы писали:
B>>>Более того, к минусам варианта с insert можно добавить то, что make_pair принимает аргументы и возвращает результат по значению.
I>>Кстати, не знаешь, аргументы-то почему по-значению?
ЮЖ>
Library Defect Report #181
ЮЖ>Discussion:
ЮЖ>The claim has surfaced in Usenet that expressions such as
ЮЖ> make_pair("abc", 3)
ЮЖ>are illegal, notwithstanding their use in examples, because template instantiation tries to bind the first template parameter to const char (&)[4], which type is uncopyable.
ЮЖ>I doubt anyone intended that behavior...
ЮЖ>Proposed resolution:
ЮЖ>In 20.2 [utility], paragraph 1 change the following declaration of make_pair():
ЮЖ>template <class T1, class T2> pair<T1,T2> make_pair(const T1&, const T2&);
ЮЖ>to:
ЮЖ>template <class T1, class T2> pair<T1,T2> make_pair(T1, T2);
...
If P is instantiated as a reference type, then the argument x is copied from. Otherwise x is considered to be an rvalue as it is converted to value_type and inserted into the map. Specifically, in such cases CopyConstructible is not required of key_type or mapped_type unless the conversion from P specifically requires it