[C++-sig] Re: indexing_v2 status update
RaoulGough at yahoo.co.uk
Mon Dec 8 17:27:58 CET 2003
David Abrahams <dave at boost-consulting.com> writes:
> Raoul Gough <RaoulGough at yahoo.co.uk> writes:
>> On the other hand, perhaps this does belong purely in the
>> ContainerTraits concept. I wonder whether assignability is always a
>> quality of a container (and all instances of it) or just the
>> particular type of value stored in a particular instance. In the case
>> of the STL containers, I think all template arguments are required to
>> be Assignable types
> Yes, but...
>> and some of the containers (set and map) add
>> const qualification somewhere in their value_type.
> ...that fact tends to make the value_type not Assignable.
Of course. I was just thinking about whether it's conceptually related
to the template arguments or rather to some property of the container
template. I guess it doesn't actually make much practical difference
in terms of providing the necessary partial specializations.
>> I've just been taking a look at the unordered_set proposal at
>> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1518.pdf and
>> it looks like the unordered_set::value_type is not const qualified,
>> which would confuse any assignability determination based on the
>> container's value_type directly.
> I'm not sure if that's intentional. I've asked.
>> On the other had, the container only
>> provides const iterators, so I guess this means that
>> unordered_set<X>::iterator::value_type is "X const",
>> and using the iterator's value type would still work.
> No, an iterator's value_type is never const.
Hmmmmm... That's really a bit of a shame, since I go to so much
trouble to pass const_iterator or iterator to the iterator_traits base
class, depending on whether the container has top-level const
qualification or not :-) Maybe this doesn't actually gain anything at
> You can look at the
> mutability of its ``reference`` type, but:
> a. the standard seems to place no requirements on the reference
> type of forward iterators
> b. It barely places requirements on the reference type of
> bidirectional iterators (you have to look for implications in
> the reverse_iterator requirements).
> c. Even having a reference type which is a reference-to-non-const
> doesn't make the value_type assignable.
Yes, you mentioned before that the reference type is not necessarily a
reliable guide. In fact, the current code relies on the iterator's
reference type and deduces the wrong value for "is_mutable" on some
>>>> For instance, std::pair<const int, int> is not
>>>> assignable, yet it doesn't have top-level const qualification, and it
>>>> *does* have an operator= (which will produce a compile-time error if
>>>> used) so I don't think any has_member_function test will help.
>>> Right. But you can provide partial specializations for
>>> std::pair<const T, const U>,
>>> std::pair<T, const U>,
>>> std::pair<const T, U>.
>> I guess the only potential problem is weirdo cases where the value
>> type appears to be assignable but the container still isn't
>> reorderable, in which case the client code would have to provide a
>> custom-written ContainerTraits anyway.
> There are a number of wierdo cases, but it all comes down to
> properties of the value type.
>> I'm thinking about some kind of
>> a dirty std::set wrapper that pretends its value_type is mutable and
>> uses const_cast internally. For motivation, see e.g.
>> or http://home.clara.net/raoulgough/map3/index.html
> I can't imagine how you plan to use this technique in this case.
Maybe it's not really a robust solution, but you could just have
wrappers that const_cast references from std::set or
std::set::iterator to remove the container's const qualification. I'm
thinking of cases where only a portion of the "value_type" is used as
a sorting key, and the remainder can be mutated at will (and
preferably in-place). The value_type is then some UDT (possibly with
safeguards to prevent key modification) which may or may not be
assignable. In fact, a vector of those values might well be
reorderable, whereas the std::set wrapper container isn't. Still, this
is stretching things a long way to try and find a counter-example.
>>>> If anyone can suggest a workable is_assignable, I'll use it to
>>>> deduce is_reorderable, but otherwise I think I'll just stick with
>>>> is_mutable_ref and explicit overrides for some containers
>>>> (i.e. std::map)
>>> I *think* I still think that's an inferior solution.
>> It's really a question of how the client code helps the library out
>> when it would get the wrong answer by itself.
>> Possible options include specializing an is_assignable template,
>> specializing a value_traits template or providing an alternative
>> ContainerTraits class (the current method).
> I am not so convinced any more that the current method is worse than
> the others.
Oh no! I'm starting to think that the value_traits or is_assignable
templates would actually be better solutions. I say "would be" because
neither of them is at all convenient to do on MSVC6 owing to the lack
of PTS. In fact, that practical difficulty probably means I'll stick
with the current method, although I'm no longer convinced it is the
best solution in theory.
More information about the Cplusplus-sig