Topic: Associative Container Compare requirements
Author: xleobx@qmailcomq.com
Date: Thu, 30 Oct 2003 22:46:32 +0000 (UTC) Raw View
"David B. Held" <dheld@codelogicconsulting.com> wrote:
> <xleobx@qmailcomq.com> wrote in message
> news:4rjmb.202$bt5.5053@iad-read.news.verio.net...
>> "David B. Held" <dheld@codelogicconsulting.com> wrote:
>> > It seems to me that the only reason one would wish to specify
>> > a Compare object when constructing a container is that the
>> > Compare object is not stateless. But if Compare is not
>> > stateless, then you would wish to copy the object after you
>>
>> How do you make that leap? I do not need to copy my collating
>> tables around, for example.
> I don't understand what you're saying.
I'm saying that I do not see a compelling reason for a container to use a
private copy of a pre-existing Compare object. A collating table is
an example - why would anyone want to copy it per every constructed
container?
>> That would be a very bad decision. If I do not need my
>> Compare objects copied, why should I suffer the
>> performance penalty?
> A) Can you cite a use case where you *wouldn't* want copying,
> *and* copying *would* induce a performance penalty?
As I said, a collating table is a good example - it is a
very big object (kilobytes).
> B) With all due respect, if you are using one of the associative
> containers provided by the SCL, the cost of copying a Compare
> object is insignificant compared to the cost of most operations
> provided by the containers.
Not necessarily. It depends on the relative frequency
of ctors vs methods.
> You typically won't need Compare to be copied when it is
> stateless. In that case, it should be an empty class, which
> should have a trivial copy c'tor. If it is a function pointer,
> the cost of copying is still rather small. Since the standard
> does not forbid an implementation from copying the compare
> object, one is free to do so. In fact, the gcc library does
> exactly that (as I suspect many implementations do), so you
> are probably already paying the "penalty".
> If you use a stateful Compare object, why *wouldn't* you
> want it copied?
Because I'd be perfectly happy with a container using a
reference to it, and I may have to jump through hoops to
reduce the performance penalty mandated by the standard.
> Consider the
> case where Compare is a function pointer. Now that I
> think of it, the compare argument in the c'tor is probably
> not even for stateful Compare objects. It is probably to
> handle the function pointer case. Unless the implementation
> attempts to detect this and treat it as a special case, it
> pretty much has to copy and store the Compare object.
> It would be fairly useless to pass a function pointer into,
> say, a map c'tor, only to have it discarded at the end of
> the c'tor execution. Since there isn't any practical,
> common use case where the Compare object is non-
> copyable, why not just formalize existing practice and
> state explicitly that it must be Copyable and that it is
> copied and stored?
Maybe to provide latitude for the implementors and to allow them
to distinguish between function pointers and objects?
Leo
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Fri, 31 Oct 2003 17:28:53 +0000 (UTC) Raw View
----- Original Message -----
From: <xleobx@qmailcomq.com>
Newsgroups: comp.std.c++
Sent: Thursday, October 30, 2003 4:46 PM
Subject: Re: Associative Container Compare requirements
> [...]
> I'm saying that I do not see a compelling reason for a container
> to use a private copy of a pre-existing Compare object. A
> collating table is an example - why would anyone want to copy
> it per every constructed container?
Because the standard forbids the container from keeping a
reference or pointer to it. I'm only making a suggestion that
is consistent with the standard. If you think the standard
should allow associative containers to store references, then
say so. But I didn't write that part of the standard, so I'm
just going with what we have.
> [...]
> > B) With all due respect, if you are using one of the associative
> > containers provided by the SCL, the cost of copying a Compare
> > object is insignificant compared to the cost of most operations
> > provided by the containers.
>
> Not necessarily. It depends on the relative frequency
> of ctors vs methods.
I would be very surprised to see an application which
frequently constructed maps or sets and infrequently used
them. I would be very suspicious of the design. Especially
when someone using such a design is concerned with
performance.
> [...]
> > It would be fairly useless to pass a function pointer into,
> > say, a map c'tor, only to have it discarded at the end of
> > the c'tor execution. Since there isn't any practical,
> > common use case where the Compare object is non-
> > copyable, why not just formalize existing practice and
> > state explicitly that it must be Copyable and that it is
> > copied and stored?
>
> Maybe to provide latitude for the implementors and to
> allow them to distinguish between function pointers and
> objects?
This isn't going to do you any good, since you don't want
the default c'ted Compare object, as I understand it; and
the container is not allowed to store a reference. My whole
point is that effectively, the standard already requires
containers to A) make a copy of the Compare object, and
B) store that object. So the copyability requirement should
essentially be stated explicitly.
Dave
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.532 / Virus Database: 326 - Release Date: 10/27/2003
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Fri, 24 Oct 2003 19:47:32 +0000 (UTC) Raw View
""Edward Diener"" <eldiener@earthlink.net> wrote in message
news:InHlb.14513$Uz6.2900@newsread1.news.atl.earthlink.net...
> "David B. Held" wrote:
> > It seems to me that the only reason one would wish to specify
> > a Compare object when constructing a container is that the
> > Compare object is not stateless.
>
> What does the Compare object being not stateless have to do
> with its ability to compare keys ?
I'm talking about constructors which allow you to pass in a
Compare object, e.g. (lifted straight from 23.3.1/2):
explicit map(const Compare& comp = Compare(),
const Allocator& = Allocator());
Now, if Compare is stateless, pray tell why anyone would
want to pass one into this c'tor (as opposed to letting the
container create one on each use, or using its own internal
copy, if it has one). It seems to me that the only reason
you would want to pass in a Compare object is because
it is *not* stateless.
> > But if Compare is not stateless, then you would wish to
> > copy the object after you are done constructing your
> > container.
>
> Why ?
Because presumably, you want to preserve whatever
Compare state was modified during construction. I mean,
why should the Compare object treat insertions at
construction differently than insertions later on? For
the case where Compare is stateless, there is effectively
no change.
Dave
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.521 / Virus Database: 319 - Release Date: 9/23/2003
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: xleobx@qmailcomq.com
Date: Sat, 25 Oct 2003 01:17:01 +0000 (UTC) Raw View
"David B. Held" <dheld@codelogicconsulting.com> wrote:
> It seems to me that the only reason one would wish to specify
> a Compare object when constructing a container is that the
> Compare object is not stateless. But if Compare is not
> stateless, then you would wish to copy the object after you
How do you make that leap? I do not need to copy my collating
tables around, for example.
> are done constructing your container. However, the standard
> does not require Compare to be copyable.
Neither does it prevent it from being copyable.
> I can't think of a reason why a stateless Compare would be
> non-copyable, and at least some stateful Compares need to
> be copied to be useful, so I think that the standard should
Useful to the user, not to the container. Therefore it is a user's
burden to provide a container with a const reference to a
useful Compare object, not a container's burden.
> require copyability. In particular, it forbids that a container
> should store a pointer or reference to a Compare object
> after construction, assignment, or copy. This is why the
> Compare object must be copied. I would further propose
> that the standard specify that the passed-in Compare object
> *is* copied and becomes the Compare object for the
> container in question, so that users have a guarantee about
> stateful Compares being propagated.
That would be a very bad decision. If I do not need my Compare objects
copied, why should I suffer the performance penalty?
> Alternatively, I propose that Compare be Copyable or
> Movable, and that when a Compare object is specified,
> that it is copied or moved at the end of the operation,
> being moved when it can, and copied when it must.
What exactly prevents you from using a copy ctor explicitly?
Leo
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sat, 25 Oct 2003 07:48:05 +0000 (UTC) Raw View
<xleobx@qmailcomq.com> wrote in message
news:4rjmb.202$bt5.5053@iad-read.news.verio.net...
> "David B. Held" <dheld@codelogicconsulting.com> wrote:
> > It seems to me that the only reason one would wish to specify
> > a Compare object when constructing a container is that the
> > Compare object is not stateless. But if Compare is not
> > stateless, then you would wish to copy the object after you
>
> How do you make that leap? I do not need to copy my collating
> tables around, for example.
I don't understand what you're saying.
> > are done constructing your container. However, the standard
> > does not require Compare to be copyable.
>
> Neither does it prevent it from being copyable.
Indeed, it does not. However, I think that containers *should*
copy Compare, in which it copyability would be a requirement.
> > I can't think of a reason why a stateless Compare would
> > be non-copyable, and at least some stateful Compares
> > need to be copied to be useful, so I think that the standard
> > should
>
> Useful to the user, not to the container. Therefore it is a user's
> burden to provide a container with a const reference to a
> useful Compare object, not a container's burden.
A const& won't do any good, because the container is
forbidden from storing pointers or references to Compare
objects. 23.1.2/11:
When an associative container is constructed by passing
a comparison object the container shall not store a pointer
or reference to the passed object, even if that object is
passed by reference. When an associative container is
copied, either through a copy constructor or an assignment
operator, the target container shall then use the comparison
object from the container being copied, as if that
comparison object had been passed to the target container
in its constructor.
> > require copyability. In particular, it forbids that a container
> > should store a pointer or reference to a Compare object
> > after construction, assignment, or copy. This is why the
> > Compare object must be copied. I would further propose
> > that the standard specify that the passed-in Compare object
> > *is* copied and becomes the Compare object for the
> > container in question, so that users have a guarantee about
> > stateful Compares being propagated.
>
> That would be a very bad decision. If I do not need my
> Compare objects copied, why should I suffer the
> performance penalty?
A) Can you cite a use case where you *wouldn't* want copying,
*and* copying *would* induce a performance penalty?
B) With all due respect, if you are using one of the associative
containers provided by the SCL, the cost of copying a Compare
object is insignificant compared to the cost of most operations
provided by the containers.
You typically won't need Compare to be copied when it is
stateless. In that case, it should be an empty class, which
should have a trivial copy c'tor. If it is a function pointer,
the cost of copying is still rather small. Since the standard
does not forbid an implementation from copying the compare
object, one is free to do so. In fact, the gcc library does
exactly that (as I suspect many implementations do), so you
are probably already paying the "penalty".
If you use a stateful Compare object, why *wouldn't* you
want it copied?
> > Alternatively, I propose that Compare be Copyable or
> > Movable, and that when a Compare object is specified,
> > that it is copied or moved at the end of the operation,
> > being moved when it can, and copied when it must.
>
> What exactly prevents you from using a copy ctor explicitly?
The fact that I don't have control over what my container
implementation does with whatever Compare object I
provide it. For instance, it isn't even required to store a
Compare object, though in practice it must. Consider the
case where Compare is a function pointer. Now that I
think of it, the compare argument in the c'tor is probably
not even for stateful Compare objects. It is probably to
handle the function pointer case. Unless the implementation
attempts to detect this and treat it as a special case, it
pretty much has to copy and store the Compare object.
It would be fairly useless to pass a function pointer into,
say, a map c'tor, only to have it discarded at the end of
the c'tor execution. Since there isn't any practical,
common use case where the Compare object is non-
copyable, why not just formalize existing practice and
state explicitly that it must be Copyable and that it is
copied and stored?
Dave
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.521 / Virus Database: 319 - Release Date: 9/23/2003
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: andreytarasevich@hotmail.com (Andrey Tarasevich)
Date: Wed, 29 Oct 2003 23:48:27 +0000 (UTC) Raw View
David B. Held wrote:
> It seems to me that the only reason one would wish to specify
> a Compare object when constructing a container is that the
> Compare object is not stateless.
That's not all. Another reason to specify a concrete comparator
parameter to the container's constructor is when you use a function
pointer, not an instance of a class as comparator:
bool lpsz_less(const char* lpsz1, const char* lpsz2)
{
return strcmp(lpsz1, lpsz2) < 0;
}
std::set<const char*, bool (*)(const char*, const char*)>
lpsz_set(&lpsz_less);
--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Wed, 22 Oct 2003 23:43:01 +0000 (UTC) Raw View
It seems to me that the only reason one would wish to specify
a Compare object when constructing a container is that the
Compare object is not stateless. But if Compare is not
stateless, then you would wish to copy the object after you
are done constructing your container. However, the standard
does not require Compare to be copyable.
I can't think of a reason why a stateless Compare would be
non-copyable, and at least some stateful Compares need to
be copied to be useful, so I think that the standard should
require copyability. In particular, it forbids that a container
should store a pointer or reference to a Compare object
after construction, assignment, or copy. This is why the
Compare object must be copied. I would further propose
that the standard specify that the passed-in Compare object
*is* copied and becomes the Compare object for the
container in question, so that users have a guarantee about
stateful Compares being propagated.
Alternatively, I propose that Compare be Copyable or
Movable, and that when a Compare object is specified,
that it is copied or moved at the end of the operation,
being moved when it can, and copied when it must.
Dave
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.521 / Virus Database: 319 - Release Date: 9/23/2003
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Thu, 23 Oct 2003 06:22:05 +0000 (UTC) Raw View
"David B. Held" wrote:
> It seems to me that the only reason one would wish to specify
> a Compare object when constructing a container is that the
> Compare object is not stateless.
What does the Compare object being not stateless have to do with its ability
to compare keys ?
> But if Compare is not
> stateless, then you would wish to copy the object after you
> are done constructing your container.
Why ?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dsp@bdal.de (Daniel Spangenberg)
Date: Thu, 23 Oct 2003 20:16:11 +0000 (UTC) Raw View
Hello David Held,
"David B. Held" schrieb:
> It seems to me that the only reason one would wish to specify
> a Compare object when constructing a container is that the
> Compare object is not stateless. But if Compare is not
> stateless, then you would wish to copy the object after you
> are done constructing your container. However, the standard
> does not require Compare to be copyable.
>
> I can't think of a reason why a stateless Compare would be
> non-copyable, and at least some stateful Compares need to
> be copied to be useful, so I think that the standard should
> require copyability. In particular, it forbids that a container
> should store a pointer or reference to a Compare object
> after construction, assignment, or copy. This is why the
> Compare object must be copied. I would further propose
> that the standard specify that the passed-in Compare object
> *is* copied and becomes the Compare object for the
> container in question, so that users have a guarantee about
> stateful Compares being propagated.
>
> Alternatively, I propose that Compare be Copyable or
> Movable, and that when a Compare object is specified,
> that it is copied or moved at the end of the operation,
> being moved when it can, and copied when it must.
>
> Dave
It is interesting, that Copyable seems not to be required for those
predicates. That leads me to the question, how the required
expressions from table 69 (p. 465)
X(c)
X a(c);
X (i, j, c)
X a(i, j, c);
a.key_comp()
a.value_comp()
can be realized without copyability of the predicates.
Are implementations allowed to return a (constant) reference of
the comparator via key_comp()? Worse than that: value_comp()
definitively needs the Copyable property, because otherwise any map
is required to store an instance of it.
My personal 0.02 EURO,
Daniel Spangenberg
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]