
"David Abrahams" <dave@boost-consulting.com> wrote in message news:usm242h75.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | | > | > yes, but in return the library only has two provide one overload | > | ^^^-"to" | > | > of begin/end. | > | | > | Meaning that you don't need a separate overload taking Seq const& just | > | to handle mutable rvalues. That's good. However, that benefit | > | doesn't depend on uglification. We could use the same old names; the | > | interface would just not be useful for mutable rvalues unless the 2nd | > | overload were provided. | > | > but now you introduce the ADL lookup problem again. | | What is "the ADL lookup problem?" the problem that emerges when you want ADL to happen, but cannot use an unqualified call because it would create conflicts between boost::begin; sequence::begin foo::begin | > | Another point is that the whole iterator/const_iterator thing is | > | artificial and broken anyway. My work has evolved towards a "cursors | > | and property maps" arrangement where cursors encode position/traversal | > | and property maps encode access. In that scheme there's no difference | > | between the cursors used when traversing constant and mutable | > | containers. Of course, if you want to be able to get read access to a | > | non-const property map rvalue you may need two overloads for that | > | purpose. | > | > How would I traverse a range in that framework? | | It depends whether the cursors are homogeneous (like iterators, the | usual case) or heterogeneous (a different type at each position). so heterogeneous means "compile-time" iteration? | The | latter requires a recursive formulation; I won't go into it here | because it's not really relevant to what we're discussing. The former | looks like: | | end_cursor<S>::type finish; | for (begin_cursor<S>::type p = sequence::begin(s); p != finish; ++p) | ... | | In either case, elements are accessed via: | | elements_type<S>::type e = sequence::elements(s); // the property map | value_type<S>::type v = e(p); // read | e(p,v); // write if e is a "map", then why dont you allow e[p] and e[p] = v ? | > | We need to decide whether we're going to accept sub-optimal | > | designs or not. If we want to use standard iterators (for which | > | there are obvious positive arguments) we are forced into some | > | compromises that we wouldn't have to accept if using cursors, | > | > How does ADL lookup change in the new framework you're working on? | ^ ^^^^^^----- redundant ;-) redundant? you will use the existing iterators as cursors then? | Only that sequences will be providing begin(s) and not | uglified_begin(s). I was going with "uglified" names like | sequence_begin() until I thought harder about Thomas' argument and | considered the likelihood of bad collisions to be low. it could fairly easily happen IMO. more and more code is put into header files qualified syntax hence becomes more important | > I don't see how it relates to the the proposed changes to | > boost.range which has as its main purpose to enable ADL lookup while | > using qualified notation. | | It's related to the argument that you only have to provide one | overload of begin/end. right, so it doesn't solve what I called "the ADL lookup problem". | > | > |AFAICS there are two ways out of this | > | > | | > | > | a) X provides the unprefixed begin as well. | > | > | > | > how does that solve anything? | > | | > | It allows clients of X to use it without boost.range. Go back and | > | read Peter Dimov's posts in this thread: http://tinyurl.com/55j7b | > | | > (http://news.gmane.org/find-root.php?message_id=%3c004801c522aa%24ee97fd10%24...). | > | Shouldn't a Boost.Range-conformant range type be usable without the | > | dispatching functions in Boost.Range? | > | > well, for vector<int> v; you can use v.begin() etc. for pair<I,I> p, you | > can use p.first etc. | | And what about a new range type that someone invents? Should they | really pick a different interface and not use something like the one | Boost.Range already provides for its ranges? So assume don't want to use boost.Range. They can use what ever syntax they want and call their functions namespace foo { iterator begin( X& ); } Assume they later want to use boost.range, just provide a simple overload namespace foo { iterator range_begin( X& r ) { return ::foo::begin(r); } } | > So I don't think that makes much sense; boost.range is a | > framework---either you use it or you don't. | | I repeat, go back and read Peter's posts in http://tinyurl.com/55j7b. | The framework ceases to own its concepts eventually. Was it the concept it its customizarion points?. I recall it as it was the costumization points that a framework ceases to own. begin() is a bad customization point; hence we need two functions. -Thorsten