Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-09-09 18:22:27

"Eric Niebler" <eric_at_[hidden]> 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

Boost list run by bdawes at, gregod at, cpdaniel at, john at