template <class T> // requires ( Has_objCmp<T> )
struct CmpComparable
{
friend bool operator < (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)<0; }
friend bool operator > (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)>0; }
friend bool operator <= (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)<=0; }
friend bool operator >= (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)>=0; }
friend bool operator == (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)==0; }
friend bool operator != (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)!=0; }
};
class SomeClass : public CmpComparable<SomeClass> // incomplete type here
{
....
};
On Mon, May 23, 2016 at 2:48 AM, Sergey Strukov <sshi...@hotmail.com> wrote:Based on my experience the main problem with the current concepts is the working with incomplete types. It makes difficult to use requirements with CRTP, for example.For instance, in the following code I cannot up requirements to the class template itself.
template <class T> // requires ( Has_objCmp<T> )
struct CmpComparable
{
friend bool operator < (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)<0; }
friend bool operator > (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)>0; }
friend bool operator <= (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)<=0; }
friend bool operator >= (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)>=0; }
friend bool operator == (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)==0; }
friend bool operator != (const T &a,const T &b) requires ( Has_objCmp<T> ) { return a.objCmp(b)!=0; }
};Because in the intended usage it would fail.
class SomeClass : public CmpComparable<SomeClass> // incomplete type here
{
....
};This problem cannot be solved by deferring the requirement check to a later phase of translation (for example, for the moment the type becomes complete),because in other situations, when the requirements are used to select implementation they must be checked immediately.I don't speak for Concepts folks, but I personally do not see this as a defect.
One purpose of concepts is to get early checking. The purpose of
CRCP is to delay checking. I don't see how you could have both.
--
You received this message because you are subscribed to the Google Groups "SG8 - Concepts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to concepts+u...@isocpp.org.
To post to this group, send email to conc...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/concepts/.
One purpose of concepts is to get early checking. The purpose of CRCP is to delay checking. I don't see how you could have both.
On 24 May 2016 at 09:31, Bjarne Stroustrup <bja...@stroustrup.com> wrote:
> One purpose of concepts is to get early checking. The purpose of CRCP is to
> delay checking. I don't see how you could have both.
Another remark: Concepts don't introduce this issue, although they
don't strive to magically solve it either.
We're talking about a case where one seemingly wants to constrain a
template parameter that is known
to be of an incomplete type. I can't fathom any other way around it
than postponing the constraints
to a point where the aforementioned type is complete.