
"Eric Niebler" <eric@boost-consulting.com> writes:
Regarding the concepts, it is correct to say, as you do, that the calls to begin(), end(), et al., must be qualified by boost::. But they also must say that the following
<quote>
is also well formed and has the same meaning:
using namespace unspecified-namespace; boost_range_begin(x);
</quote>
That doesn't look right to me. First of all, it seems to me that telling users that using namespace unspecified-namespace; ^^^^^^^^^^^^^^^^^^^^^ is well-formed is next to useless. How is a user supposed to satisfy that requirement? Am I missing something? Secondly, and I could be wrong, but I don't think that statement can be true for some of the types modeling range.
I think you should also say somewhere (but not necessarily in the Concepts section) that unspecified-namespace contains the implementations of boost_range_begin(), et al., for the std containers, std::pair, arrays and null-terminated strings. I think that should do it. Does anybody have a better suggestion?
The Range concepts have been a fruitful source of confusion. I'm still myself a bit puzzled sometimes :-)
We want to say a range r supports the expressions
boost::begin(r) boost::end(r) boost::size(r)
That is true fo certain types if we do include a certain header, otherwise it is not. That has really irritated me: in one translation-unit T could be conforming to a range, in others it need not to.
One way to solve that is to bite the bullet and always #include the necessary headers to make the statements of conformance consistent. Another possible option is to do that on compilers you don't know about, and on others intrude on namespace std and inject the forward declarations. As long as you make sure they match the real declarations, and you test it to make sure the compiler will accept it, you can get away with it. I know it's technically illegal but for some reason that doesn't rise to the level of a concern for me.
If you want to treat a type as a range, you need to include the file that makes that type a conforming range. I don't see any problem with that.
I do. Does the type satisfy the concept or doesn't it? Normally, that question is (and should be) answerable based on the visibility of the type alone.
If we use your quote above, it seems to me that the to expressions are not equivalent: you can't exchange one with the other.
Why not?
A Range concept is composed of more than the concept defining boost_range_begin()/boost_range_end().
For what it's worth to anyone, I agree with Thorsten here.
Of course. And I'm saying that for a type to conform to the range concept, it must do more than ensure that boost::begin(), boost::end(), and boost::size() are well-formed and have the proper semantics.
Aside from defining the correct traits to deduce the return types of these functions, that's all it must do. Concepts are for describing the requirements of generic algorithms.
I'm suggesting that you *add* the following requirements _in addition to_ the ones already listed:
using namespace unspecified-namespace; boost_range_begin(r);
is well-formed and has the same semantics as boost::begin(r). And the same for boost_range_end() and boost_range_size().
I know what you're trying to accomplish, but I think the correct approach is to document what boost::begin() et. al do. After all, for a specific concrete type the user could explicitly specialize boost::begin() et al. There's no need to provide an ADL overload.
We might want to say the following:
T models a Range if it models one of the following concepts
???
Yeah I don't understand that either. -- Dave Abrahams Boost Consulting www.boost-consulting.com