Boost logo

Boost :

Subject: Re: [boost] [contract] SFINAE question for concepts
From: Matt Calabrese (rivorus_at_[hidden])
Date: 2012-10-03 19:41:31


On Wed, Oct 3, 2012 at 4:02 PM, Lorenzo Caminiti <lorcaminiti_at_[hidden]>wrote:

> Hello all,
>
> I have a SFINAE question. The following correctly returns false for
> eq1<x>::value when x has no operator==

I encountered the same problem in GCC when developing Generic, only with
constructor-style initialization at the time -- I thought it was just a
compiler bug, but since Clang is doing it too, maybe it's not. What I
assumed was happening was that since it's in an unevaluated context, the
compiler realized it could get the sizeof the expression without needing to
know anything about the type of the subexpression, so it [incorrectly] only
did syntax checking on it. In other words, it short-circuits before doing
substitution so SFINAE never rules it out. However, I'm testing it now when
not inside of a place where SFINAE may occur (though still with template
arguments), and I correctly get an error when the template is instantiated.
This is true with both GCC and Clang, so it seems like this unintuitive
behavior may, in fact, be standard. I don't have time to check it out right
now, but if someone references the standard and still can't figure out why
you're getting this behavior, you could always submit a bug report to
Clang. They're versed enough in standardese to determine if it's standard
behavior or not.

I'd say that you could use a workaround, but I assume you want the {}
syntax so that you could do the N3351 syntax for expression validation
directly.

Also, I'm going to warn you now because I went down this same exact path
with Generic -- you're going to have to change your approach for
representing givens -- datamembers and even function parameters will not
work. The problem is, you need to account for checking of "void", but with
this implementation, you'll get a hard error instead of a compile-time bool
value. You need to get everything into a context where SFINAE can take
place. My approach with the old-style generic was to do all of the checking
in a template specialization pattern list (as opposed to in a function
template definition), and I used template reference parameters for the
givens.

-- 
-Matt Calabrese

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