Здравствуйте, Qbit86, Вы писали:
CC>>При ситуации отсутстыия по какой либо причине исключений сколь либо вменяемый fail для operator[] реализовать не представляется возможным. Поэтому ИМХО по другому никак.
Не знают как — пусть параметризуют тип стратегиями. Хотя бы чтоб можно было подсунуть свой код для конструирования объекта по умолчанию. Можно кидать исключения при вызове через [] отстутствующего элемента в константном контейнере.
Q>Вот и приходится для доступа использовать метод find(), а для вставки — insert(). Operator [] вообще могли бы не делать.
+1. И для полного счастья нет константной реализации.
void foo(const std::map<int, int> &m)
{
cout<<m[1]<<endl; // error: passing `const std::map<int, int ... skipped ... discards qualifiers|
}
Q>А по другому реализовать можно, например, вернуть из оператора «опцион», специальное размеченное объединение (в терминологии ФП, а не C++). В .NET'е можно было бы вернуть null, в плюсах, быть может, boost::optional<V>:
Q>Q>boost::optional<V> v = my_map[key];
Q>if (!v) {
Q> // Обработать отсутствие.
Q>}
Q>else {
Q> V const value = v.get();
Q>}
Q>
Да. Тоже вариант.
Здравствуйте, Mazay, Вы писали:
AG>>Для мапы с интами вполне работает []
AG>>std::map<int, int> m;
AG>>++m[3]; // m[3] теперь == 1
M>Хм. Это гарантируется Стандартом?
http://ra.dkuug.dk/jtc1/sc22/open/n2356/lib-containers.html#lib.map.access
(*((insert(make_pair(x, T()))).first)).second.
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, Mazay, Вы писали:
AG>>>Для мапы с интами вполне работает []
AG>>>std::map<int, int> m;
AG>>>++m[3]; // m[3] теперь == 1
M>>Хм. Это гарантируется Стандартом?
AG>http://ra.dkuug.dk/jtc1/sc22/open/n2356/lib-containers.html#lib.map.access
AG>AG> (*((insert(make_pair(x, T()))).first)).second.
AG>
Это понятно. Пришлось самому лезть в Стандарт:
8.5 Initializers [dcl.init]
...................
To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
...................
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
...................
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
Видимо таки гарантируется. Но всё равно лучше бы иметь возможность подсунуть свою фабрику. Чтоб было так:
(*((insert(make_pair(x, DefaultFactory()))).first)).second.
, где DefaultFactory — параметр тип для map.