Boost logo

Boost :

From: Doug Gregor (dgregor_at_[hidden])
Date: 2006-04-12 09:43:12

On Apr 12, 2006, at 9:25 AM, Peter Dimov wrote:
> Doug Gregor wrote:
>> When we initially type-check lower_bound, we need to determine if
>> there is an advance() that we can call. Both #1 and #2 have been
>> seen, so we check them. Can we call #1? Sure, because every
>> ForwardIterator is also an InputIterator. Can we call #2? Nope, our
>> ForwardIterator is not guaranteed to be a BidirectionalIterator. So,
>> we call #1 our "seed" function and use it for type-checking the
>> template. Type-checking succeeds.
> Question #1, what happens when there is no seed?

Type-checking of the template definition fails.

>> Now, let's consider what happens with this call to lower_bound:
>> vector<int> v; lower_bound(v.begin(), v.end(), 17);
>> When instantiating a template that uses concepts, we don't perform
>> the normal second phase lookup with ADL. Instead, we do a more
>> limited lookup designed to make sure that instantiation cannot fail
>> [*]. So, when we instantiate the call to advance() in lower_bound(),
>> we start with our "seed" function #1. We then look for any other
>> functions named "lower_bound" in the same namespace as our seed that
>> are specializations of the seed, and add those functions to our
>> candidate set along with the seed.
> Question #2, what happens in the swap() case? The seed (if there's
> one) is
> std::swap, but the actual call must go to the specialized swap in
> the type's
> namespace.

In that case, you'll need a Swappable concept in your requirements:

   auto concept Swappable<typename T> {
     void swap(T&, T&);

We'll still define std::swap, of course:

   template<typename T> where CopyConstructible<T> && Assignable<T>
   void swap(T& x, T& y);

The "auto" means that we get implicit matching for the concept, which
will either fall back to the swap() definition above or will find a
more specialized swap in the type's namespace.


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