Boost logo

Boost :

From: Douglas Gregor (doug.gregor_at_[hidden])
Date: 2006-08-21 10:17:42


On Aug 20, 2006, at 11:48 PM, David Abrahams wrote:
>> 3) The concepts can be built up from primitives using and_ and or_
>> and not_
>> operations, just like in Stroustrup's proposals. For example, the
>> concept
>> above could have included this statement instead: "typedef
>> and_<CONCEPTS_USE_PATTERN(b = left < right), CONCEPTS_USE_PATTERN
>> (b = right
>> < left), copy_constructible<left> > constraints;"
>
> I think I'd better leave it to Doug Gregor to explain why "or"
> constraints are problematic.

They are problematic for technical reasons (e.g., one needs to type-
check a template an exponential number of times when it uses or
constraints), but the real issue with or constraints is that they
aren't sufficiently motivated. I've never actually needed them myself
(ever), and the two examples I've seen have better solutions. For
example, consider an abs() function that can work for either Integral
or Floating-point types:

   template<typename T> where Integral<T> || Floating<T> T abs(T x);

Or constraints work here, but we could just as easily have used a
different concept (say, "Numeric") that better matches the
requirements of abs:

   template<typename T> where Numeric<T> T abs(T x);

To make this formulation equivalent to the one using ||, we need to
ensure that all Integral and Floating types are also Numeric. With
the benefit of foresight, we would have made Integral and Floating
refinements of Numeric:

   concept Numeric<typename T> { ... }
   concept Integral<typename T> : Numeric<T> { ... }
   concept Floating<typename T> : Numeric<T> { ... }

Even without foresight, we're fine: just write two "concept map"
templates that turn Integral and Floating types into Numeric types:

   template<Integral T> concept_map Numeric<T> {}
   template<Floating T> concept_map Numeric<T> {}

So, our new abs() works with both Integral and Floating types, like
the || version, but it's better in several ways. First, the compiler
only needs to type-check abs() once (not twice). Second, the
declaration of abs() more closely reflects its actual requirements.
Finally, abs() can now be used with any Numeric type---even those
that are neither Integral nor Floating, such as rational numbers.

I am, of course, very interested in seeing real-world examples using
||. Every example I've seen is better implemented without it. Of
course, assuming we do have some real-world use cases, someone still
needs to figure out how to implement || constraints without an
exponential blow-up.

>> 4) This use pattern syntax more closely resembles the C++0x use
>> pattern
>> proposals than any other existing library.
>
> Unless you're looking at the wrong proposals ;-)
>
> Usage patterns don't really work for compiler support of concept
> checking, because they hide intermediate types that need to be
> explicit.

There is some work on trying out usage patterns for real, in the
context of ConceptGCC. I don't know the status, but eventually it
should show us just how critical those intermediate types are.

> Well, it looks really interesting (really!), but I think you should
> review the ConceptC++ publications, in particular N1849, before
> investing more time in it. Also, IMO, you should try to model the
> standard concepts and see how it works out in practice.

I strongly suggest that we focus on the latest concept proposal,
N2042. N2042 is the result of countless hours of discussions among
the authors of the two different concepts proposals, and it is the
only concepts proposal that will be moving forward.

You can find up-to-date information on the concepts proposals,
compiler, etc. on the ConceptC++ home page:

        http://www.generic-programming.org/languages/conceptcpp/

        Cheers,
        Doug


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk