Boost logo

Boost :

Subject: Re: [boost] [contract] concept error messages
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-10-08 12:16:55


On Mon, Oct 8, 2012 at 5:57 AM, Andrzej Krzemienski <akrzemi1_at_[hidden]> wrote:
>> >> >> Lots of reasons, but mostly it clearly delineates what is required
>> >> >> from what is returned.
>> >> >>
>> >> >
>> >> > I agree with you that requires is important, particularly for
>> >> concept-based
>> >> > overloads where one overload has more refined concepts than another
>> >>
>> >> Can you guys give me an example of this?
>> >
>> >
>> > std::advance, even in the C++98 standard library, is overloaded
>> differently
>> > for input iterators than it is from bidirectional and random access
>> > iterators. With random access iterators, advance operates in constant
>> time.
>> > With input iterators, advance operates linearly.
>>
>> Sure, I understand:
>>
>> template< class I, class Distance >
>> requries InputIterator<I>
>> void advance( I& it, Distance n ) { /* linear complexity... */ }
>>
>> template< class I, class Distance >
>> requries BidirectionalIterator<I>
>> void advance( I& it, Distance n ) { /* ... */ }
>>
>> template< class I, class Distance >
>> requries RandomAccessIterator<I>
>> void advance( I& it, Distance n ) { /* constant complexity... */ }
>>
>> I agree, this type of overloading is a reason for having requires,
>> enable_if will not suffice. Is there any other reason?
>>
>
> One (perhaps minor) reason is that enable_if is an ugly workaround rather
> than a decent solution for the problem. enable_if is a class template. WHen
> using it in declaring your function template you have to choose how you
> want to "uglify" your declaration:
> (1) Uglify the return type?
> (2) Add a useless function argument?
> (3) Add a useless template parameter?
>
> "requires" on the other hand gives you another section in the declaration
> that does not interfere with function arguments or return value. This is
> only a problem of enable_if. If we have "mini-concepts" in form of
> static-if, the argument above would not hold anymore.

This is a problem of enable_if so I don't consider it a rationale for
requires. As I briefly mentioned before, if the ugly enable_if is a
concern in either forms:

template< typename T, BOOST_ENABLE_IF(EqualityComparable<T>)>
bool equal ( T const& a, T const& b );

template< typename T >
typename std::enable_if<EqualityComparable<T>, bool>::type
equal ( T const& a, T const& b );

Then I'll just provide a syntax similar to what is proposed by N3329:

BOOST_CONTRACT_FUNCTION(
    template( typename T )
    bool (equal) ( (T const&) a, (T const&) b )
        if(EqualityComparable<T>)
) ;

And same thing for class templates. Of course, if I end-up providing
requires for the reason(s) 1) (and maybe 2)) below then you can use
requires instead of enable_if and there's no point for me to also
provide this N3329 "if" syntax.

1) Supporting concept based overloading/specializations is a valid
argument for having requires as it cannot be done with enable_if (as
Matt pointed out):

template< class I, class Distance >
   requries InputIterator<I>
void advance( I& it, Distance n ) { /* linear complexity... */ }

template< class I, class Distance >
   requries BidirectionalIterator<I>
void advance( I& it, Distance n ) { /* ... */ }

template< class I, class Distance >
   requries RandomAccessIterator<I>
void advance( I& it, Distance n ) { /* constant complexity... */ }

2) Another valid argument for requires is that the compiler will give
the algorithm implementer an error if he/she uses the type in a way
that doesn't model the concept (as Matt pointed out):

template< typename T >
    requires EqualityComparable<T>
bool equal ( T const& a, Tconst& b)
{
    T x = a; // compiler error: T is not CopyConstructible, it's just
EqualityComparable
    ...
}

Unfortunately, I don't think I can do this in a lib :( Can I? Does
Boost.Generic provide such errors?

Finally: is there any argument other than 1) and 2) for having requires?

Thanks!
--Lorenzo


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