Topic: Defect report: std::map not a container


Author: pdimov@techno-link.com
Date: 2000/11/09
Raw View
In article <hinnant-0811002053460001@ith3-420.twcny.rr.com>,
  hinnant@anti-spam_metrowerks.com (Howard Hinnant) wrote:
> In article <8ubmrm$ifl$1@nnrp1.deja.com>, pdimov@techno-link.com
wrote:
>
> | list::assign(first, last) is defined (23.2.2.1/7) as being
equivalent to
> |
> | erase(begin(), end()); insert(begin(), first, last);
> |
> | so I think that it can't use T::operator= to perform the
assignment; a
> | destructor/copy-constructor sequence is implied. The other
list::assign
> | overload has a similar "Effects" clause.
> |
> | Perhaps I interpret the "Effects" clause too strictly?
>
> I hope so.  I would like to think there is a big "as if" in there
> (especially since assignable IS currently required).  I agree it can
be
> quite a large gray area as to when and how far "as if" will take
you.  But
> taking advantage of assignable can be a significant performance
advantage
> over erase/insert.

I think that this issue probably deserves a DR of its own. "As if", in
the usual sense, doesn't apply... no "as if" rule can justify replacing
an erase/insert sequence (that is defined to invoke size() destructors
(23.2.2.3/5) and last - first copy constructors (23.2.2.3/2)) with a
loop that calls T::op=. Especially if some T operation throws an
exception. Consider also the fact that if insert'ing a single element
throws, the insert() is guaranteed to have no effect (23.1/10).

The "as if" rule, however, may be legitimately used to avoid
deallocating and reallocating memory, minimizing the performance loss.

> | In any event, wouldn't it be possible to require that T be
Assignable
> | only if the methods in question are actually used? (An explicit
> | instantiation of std::list<T> would be considered an 'use'.)
>
> Throw in assign and you've got a deal. ;-)

Oh, I already did - "methods in question". :-)

--
Peter Dimov
Multi Media Ltd.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Peter Dimov" <pdimov@mmltd.net>
Date: 2000/11/07
Raw View
 [Moderator's note: this defect report has been
 forwarded to the C++ committee. -moderator(fjh).]

Section: 23.1 [lib.container.requirements], 23.3.1 [lib.map], 23.3.2
[lib.multimap]

23.1/3 states that the objects stored in a container must be Assignable.
23.3.1/2 states that map satisfies all requirements for a container, while
in the same time defining value_type as pair<const Key, T> - a type that is
not Assignable.

It should be noted that there exists a valid and non-contradictory
interpretation of the current text. The wording in 23.1/3 avoids to mention
value_type, referring instead to "objects stored in a container." One might
argue that map does not store objects of type map::value_type, but of
map::mapped_type instead, and that the Assignable requirement applies to
map::mapped_type, not map::value_type.

However, this makes map a special case (other containers store objects of
type value_type) and the Assignable requirement is needlessly restrictive in
general.

For example, the proposed resolution of active library issue #103 is to make
set::iterator a constant iterator; this means that no set operations can
exploit the fact that the stored objects are Assignable.

Proposed resolution:

Remove the requirement that the objects stored in a container be Assignable
from 23.1/3 and reintroduce it on a case by case basis (for vector and
deque.)

Rationale:

list, set, multiset, map, multimap are able to store non-Assignables.

--
Peter Dimov
Multi Media Ltd.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: hinnant@anti-spam_metrowerks.com (Howard Hinnant)
Date: 2000/11/07
Raw View
In article <8u9agl$ont$1@weber.techno-link.com>, "Peter Dimov"
<pdimov@mmltd.net> wrote:

|         [Moderator's note: this defect report has been
|         forwarded to the C++ committee. -moderator(fjh).]
|
| Section: 23.1 [lib.container.requirements], 23.3.1 [lib.map], 23.3.2
| [lib.multimap]
|
| 23.1/3 states that the objects stored in a container must be Assignable.
| 23.3.1/2 states that map satisfies all requirements for a container, while
| in the same time defining value_type as pair<const Key, T> - a type that is
| not Assignable.
|
| It should be noted that there exists a valid and non-contradictory
| interpretation of the current text. The wording in 23.1/3 avoids to mention
| value_type, referring instead to "objects stored in a container." One might
| argue that map does not store objects of type map::value_type, but of
| map::mapped_type instead, and that the Assignable requirement applies to
| map::mapped_type, not map::value_type.
|
| However, this makes map a special case (other containers store objects of
| type value_type) and the Assignable requirement is needlessly restrictive in
| general.
|
| For example, the proposed resolution of active library issue #103 is to make
| set::iterator a constant iterator; this means that no set operations can
| exploit the fact that the stored objects are Assignable.
|
| Proposed resolution:
|
| Remove the requirement that the objects stored in a container be Assignable
| from 23.1/3 and reintroduce it on a case by case basis (for vector and
| deque.)
|
| Rationale:
|
| list, set, multiset, map, multimap are able to store non-Assignables.

I object to list being included in this group, at least if
list<T>::operator= or list<T>::assign is instantiated.  The assignable
properties of T can be put to good use in these methods.

-Howard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: pdimov@techno-link.com
Date: 2000/11/08
Raw View
In article <hinnant-0711001656520001@ith3-43f.twcny.rr.com>,
  hinnant@anti-spam_metrowerks.com (Howard Hinnant) wrote:
> In article <8u9agl$ont$1@weber.techno-link.com>, "Peter Dimov"
> <pdimov@mmltd.net> wrote:
>
> | list, set, multiset, map, multimap are able to store non-
Assignables.
>
> I object to list being included in this group, at least if
> list<T>::operator= or list<T>::assign is instantiated.  The assignable
> properties of T can be put to good use in these methods.

list::assign(first, last) is defined (23.2.2.1/7) as being equivalent to

erase(begin(), end()); insert(begin(), first, last);

so I think that it can't use T::operator= to perform the assignment; a
destructor/copy-constructor sequence is implied. The other list::assign
overload has a similar "Effects" clause.

Perhaps I interpret the "Effects" clause too strictly?

For list::operator=, I agree; it's possible to exploit the Assignable
properties of T. I'm not sure how such an implementation can be made
exception-safe, provided that this is a design goal, of course.

In any event, wouldn't it be possible to require that T be Assignable
only if the methods in question are actually used? (An explicit
instantiation of std::list<T> would be considered an 'use'.)

--
Peter Dimov
Multi Media Ltd.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: hinnant@anti-spam_metrowerks.com (Howard Hinnant)
Date: 2000/11/09
Raw View
In article <8ubmrm$ifl$1@nnrp1.deja.com>, pdimov@techno-link.com wrote:

| list::assign(first, last) is defined (23.2.2.1/7) as being equivalent to
|
| erase(begin(), end()); insert(begin(), first, last);
|
| so I think that it can't use T::operator= to perform the assignment; a
| destructor/copy-constructor sequence is implied. The other list::assign
| overload has a similar "Effects" clause.
|
| Perhaps I interpret the "Effects" clause too strictly?

I hope so.  I would like to think there is a big "as if" in there
(especially since assignable IS currently required).  I agree it can be
quite a large gray area as to when and how far "as if" will take you.  But
taking advantage of assignable can be a significant performance advantage
over erase/insert.

| For list::operator=, I agree; it's possible to exploit the Assignable
| properties of T. I'm not sure how such an implementation can be made
| exception-safe, provided that this is a design goal, of course.

It is quite easy to give it the weak guarantee.  To give it the strong
guarantee you spend twice the memory - which your clients may or may not
like.  The erase/insert sequence specifies that only the weak guarantee is
in effect.  If clients want a strong guarantee assign they can build one.
But they can't necessarily build a less expensive weak guarantee assign:

template <class Container>
void my_strong_assign(Container& x, const Container& y)
{
   Container temp(y);
   x.swap(temp);
}

| In any event, wouldn't it be possible to require that T be Assignable
| only if the methods in question are actually used? (An explicit
| instantiation of std::list<T> would be considered an 'use'.)

Throw in assign and you've got a deal. ;-)

-Howard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]