Boost logo

Boost :

Subject: Re: [boost] Provisional Boost.Generic and Boost.Auto_Function (concepts without concepts)
From: Dave Abrahams (dave_at_[hidden])
Date: 2010-12-16 09:18:17


On Wed, Dec 15, 2010 at 2:23 PM, Matt Calabrese <rivorus_at_[hidden]> wrote:
> Alright, I'm updating the way concept maps are defined and I'd like some
> feedback here before I go through the task of creating yet another
> named-parameter macro. In designing Generic, I've gone in a slightly
> different direction from what would have been C++0x concepts and concept
> maps. In particular, instead of having "auto concepts", all concepts are by
> default explicit, however, a programmer can create one or more "auto concept
> maps" for a given concept. These "auto concept maps" act as concept maps
> with optional conditions (SFINAE and metafunction conditions).

That sort of sounds like concept map templates with SFINAE "tacked on"
(just the same way we tacked on SFINAE to partial template
specialization—though most people don't know that usage of enable_if).
 Would you support the analogue of concept map templates that can be
partially-ordered (sounds from what you write below like you would),
or would we be writing SFINAE conditions like "if (InputIterator<X> &&
!BidirectionalIterator<X>)" to avoid ambiguities?

> For instance, there has been concern in the C++ community about making
> iterator concepts, not to mention many other concepts, auto. I side with the
> explicit crowd and agree that most concepts should be be explicit, including
> iterator concepts, however, given certain conditions, I believe that it is
> acceptable for types that pass some kind of basic compile-time check to be
> automatically mapped if the superficial requirements of the concept are met.

I think it's particularly important for foundational concepts like
EqualityComparable.

> If it's not clear what I mean, here is an example:
>
> //////////
> BOOST_GENERIC_CONCEPT_MAP
> ( ( template ( (class) T ) )
> , (ForwardIterator)( T )
> , ( if ( check_if_T_uses_the_boost_forward_iterator_helper_base< T > ) )
> )
> (
> // Empty implementation
> )
> //////////
>
> In the above code we have an auto concept map for ForwardIterator that only
> applies to types which inherit from forward_iterator_helper of
> Boost.Operators. In addition to the explicitly specified "if" check, it will
> also implicitly check via SFINAE all of the syntactic concept requirements.
> The idea is that if a class uses the iterator helper base then it is likely
> trying to be a forward iterator. While this is not entirely true 100% of the
> time (a quick example is another intermediate base that uses this helper
> base), it should be safe and useful in practice and is IMO a better
> alternative to fully auto concepts, and it should alleviate the need for
> programmers creating iterators to have to manually make empty concept maps
> in many situations.
>
> First, I'd like to get some feedback on this approach before I take the time
> to fully implement it. Does the idea of "auto concept maps" as opposed to
> "auto concepts" make sense?

This sounds like the exact opposite of what Bjarne tried to do with
his last minute proposal of "explicit concept maps instead of non-auto
concepts." IMO, you're both going too far in one direction, so I'll
give you the analogous answer to the one I gave him: If you can do
full auto concepts, you should, because people will be able to, and
will, use your mechanism to create the equivalent thing anyhow—it'll
just be uglier.

> What problems may arise from this? One thing
> that may initially appear to be a problem is that you can have two auto
> concept maps with overlapping conditions, in which case the auto concept map
> to use would be ambiguous. This problem can be alleviated by explicitly
> specifying a non-auto concept map which would be preferred over the auto
> maps. The rules for which concept maps get picked are the same as they are
> for matching template specializations that have (optional) Enable_If style
> conditions, as that's how everything is implemented underneath the hood, so
> the method of disambiguation should be fairly familiar to C++ programmers.

Sounds perfect.

> If anyone sees any problems with this approach, please let me know, as it
> will save me a lot of effort if there are any as-of-yet unforeseen
> show-stopping problems.

The kinds of things you're proposing won't kill the feature; it's all
a question of expressiveness and usability at this level.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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