
On 06/10/12 12:03, Lorenzo Caminiti wrote:
On Fri, Oct 5, 2012 at 5:23 PM, Andrew Sutton <asutton.list@gmail.com> wrote:
One point of discussion is: In case a type doesn't model a concept, should the compiler generate an hard error or the function/class template should simply be removed from the overload/specialization set?
I think it's best to remove templates from the overload set or specialization matching. In other words, check constraints early and check constraints often. You should only really get "hard" concept errors when you actually end up trying to use a bad overload or specialization.
Using concept (boolean meta-functions) with enable_if should be sufficient then -- just option A):
template< typename T > typename std::enable_if< AlwaysTrue<T>::value && contract::std::EqualityComparable<T>::value, bool>::type equal1 ( T const& a, T const& b ) { return a == b; }
And given this, I personally don't see the need for specifying concepts in place of typename or using requires. In other words, I think the above use of enable_if is sufficient and the following syntax is not necessary (even if it's part of N3351):
template< AlwaysTrue T > requires contract::std::EqualityComparable<T> bool equal1 ( T const& a, T const& b ) { return a == b; }
What would be the purpose of supporting this syntax given that we can equivalently use enable_if (which is already part of the standard)?
One potential difference is concept refinement. Suppose you have two overloaded functions taking, say, ForwardIterator and RandomAccessIterator. If you pass a type that works for both then for concepts the compiler should pick the RandomAccessIterator overload, but with enable_if it should be ambiguous. John Bytheway