On 08/01/2014 08:22 AM, Robert Ramey wrote:
b) settlement of "best practice in the real world" of implementation of this idea. I recommended Boost Concept Check. Which isn't bad for a start, but isn't perfect either. I ideally I would like to see this used where its a good fit and an alternative for cases where it isn't.
Boost Concept Check is horribly dated and very limited, IMO. For my work on a new range library[*], I built a new concept check library for C++11. You define a concept like: namespace concepts { struct BidirectionalIterator : refines<ForwardIterator> { template<typename I> auto requires_(I i) -> decltype( concepts::valid_expr( concepts::model_of<Derived>( category_t<I>{}, std::bidirectional_iterator_tag{}), concepts::has_type<I &>(--i), concepts::has_type<I>(i--), concepts::same_type(*i, *i--) )); }; } template<typename I> using BidirectionalIterator = concepts::models<concepts::BidirectionalIterator>; Then you can use it like a constexpr Boolean function in enable_if, which can be conveniently wrapped in a simple macro like: template<typename I, CONCEPT_REQUIRES_(BidirectionalIterator<I>())> void advance(I i, iterator_difference_t<I> n) { // ... } There's even a form that you can use on (non-template) member functions without causing a hard error: template<typename I> struct wrapper { void next() { ... } CONCEPT_REQUIRES(BidirectionalIterator<I>()) void prev() { ... } }; Types like concepts::BidirectionalIterator can be used like tags for the sake of tag dispatching, a poor man's concept-based overloading. I highly recommend working this way if your compiler is man enough. My range effort would have been DOA without it. And to answer the inevitable question, I'm not opposed to getting this into Boost, but it's pretty far down my list of priorities right now. If someone wanted to take this work and run with it, I'd be overjoyed. Eric [*] http://www.github.com/ericniebler/range-v3