Topic: How do allocators become unequal?
Author: "Bo Persson" <bop@gmb.dk>
Date: Thu, 19 Nov 2009 17:17:14 CST Raw View
Bo Persson wrote:
> In C++98 the allocator requirements [lib.allocator.requirements]
> contains a special permission for standard containers:
>
> "All instances of a given allocator type are required to be
> interchangeable and always compare equal to each other."
>
>
> For C++0x this sentence has been removed, obviously with the
> intention that containers should be able handle allocators that
> compare unequal. However, in N3000 Table 40 requires that a copy
> constructed allocator must compare equal to the original:
>
> X a1(a); Shall not exit via an exception. post: a1 == a
>
>
> So, if a copy of an allocator is always required to be equal to the
> original, how and when can it ever become unequal?
>
>
> The answer to this has an effect on std::list::splice, which is
> undefined if L1.get_allocator() != L2.get_allocator(). Is it the
> intention that this could happen for:
>
> std::list<type, my_allocator> L1;
> std::list<type, my_allocator> L2;
>
> but never for
>
> std::list<type, my_allocator> L1;
> std::list<type, my_allocator> L2(L1);
>
> ?
>
>
>
> Bo Persson
Ok, I have figured this out now.
(Answering my own posting :-)
In the last case, the copy constructor for L2 does in fact not always
copy construct from L1's allocator. It has to call
allocator_traits<my_allocator>::select_on_container_copy_construction,
which just might return a totally different instance of the allocator.
So, if L2's allocator is in fact not copy constructed from L1 (even
though the rest of L2 is), the allocators may then compare unequal.
That does not contradict the requirement that a copy must compare
equal to the original. Phew!
Bo Persson
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Fri, 20 Nov 2009 11:36:25 CST Raw View
On Nov 20, 12:17 am, "Bo Persson" <b...@gmb.dk> wrote:
> Bo Persson wrote:
> > In C++98 the allocator requirements [lib.allocator.requirements]
> > contains a special permission for standard containers:
>
> > "All instances of a given allocator type are required to be
> > interchangeable and always compare equal to each other."
>
> > For C++0x this sentence has been removed, obviously with the
> > intention that containers should be able handle allocators that
> > compare unequal. However, in N3000 Table 40 requires that a copy
> > constructed allocator must compare equal to the original:
>
> > X a1(a); Shall not exit via an exception. post: a1 == a
>
> > So, if a copy of an allocator is always required to be equal to the
> > original, how and when can it ever become unequal?
>
> > The answer to this has an effect on std::list::splice, which is
> > undefined if L1.get_allocator() != L2.get_allocator(). Is it the
> > intention that this could happen for:
>
> > std::list<type, my_allocator> L1;
> > std::list<type, my_allocator> L2;
>
> > but never for
>
> > std::list<type, my_allocator> L1;
> > std::list<type, my_allocator> L2(L1);
>
> > ?
>
> > Bo Persson
>
> Ok, I have figured this out now.
>
> (Answering my own posting :-)
>
> In the last case, the copy constructor for L2 does in fact not always
> copy construct from L1's allocator. It has to call
> allocator_traits<my_allocator>::select_on_container_copy_construction,
> which just might return a totally different instance of the allocator.
>
> So, if L2's allocator is in fact not copy constructed from L1 (even
> though the rest of L2 is), the allocators may then compare unequal.
> That does not contradict the requirement that a copy must compare
> equal to the original. Phew!
I don't consider that as "phew", because the individual allocator of
a
container is not part of its /salient attributes/ (i.e., one that
contributes
to its value according to the nomenclature of
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2479.pdf
). A good litmus test for this is, that neither operator== nor any
other
value-related accessor of the container depends on the allocator
*value*.
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Bo Persson" <bop@gmb.dk>
Date: Thu, 19 Nov 2009 13:27:26 CST Raw View
In C++98 the allocator requirements [lib.allocator.requirements]
contains a special permission for standard containers:
"All instances of a given allocator type are required to be
interchangeable and always compare equal to each other."
For C++0x this sentence has been removed, obviously with the intention
that containers should be able handle allocators that compare unequal.
However, in N3000 Table 40 requires that a copy constructed allocator
must compare equal to the original:
X a1(a); Shall not exit via an exception. post: a1 == a
So, if a copy of an allocator is always required to be equal to the
original, how and when can it ever become unequal?
The answer to this has an effect on std::list::splice, which is
undefined if L1.get_allocator() != L2.get_allocator(). Is it the
intention that this could happen for:
std::list<type, my_allocator> L1;
std::list<type, my_allocator> L2;
but never for
std::list<type, my_allocator> L1;
std::list<type, my_allocator> L2(L1);
?
Bo Persson
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]