"SFINAE is Evil"

Bill Baxter dnewsgroup at billbaxter.com
Sun Mar 23 18:20:01 PDT 2008


 > Bill Baxter Wrote:
 >
 >> Jason House wrote:
 >>> I should probably expand this question...
 >>>
 >>> Who uses templates in D? What is the most complex use you've done? 
Do you ever plan to get more complex? Would SFINAE make your life easier 
or harder?
 >>>
 >>> I've written templates classes that have one definition, and used 
static if as needed for specialization. I don't forsee more complex 
usage and view SFINAE as something that would mask bugs.
 >> I don't have time to write more right now, but
 >> Lutz Kettner gives a pretty good examples of using SFINAE here:
 >> 
http://www.mpi-inf.mpg.de/~kettner/courses/lib_design_03/notes/meta.html#Constraining
 >> 
http://www.mpi-inf.mpg.de/~kettner/courses/lib_design_03/notes/meta.html#Classification

Jason House wrote:
> I look forward to when you can write more... Are you trying to say SFINAE is needed? 

Yes, I'm saying I haven't yet found a case where I'm using it (but that 
doesn't mean there isn't one!)

However, I did start a thread a while back about a way to introduce 
/controlled/ SFINAE.  Or rather a way to explicitly say you want to try 
something, and if it does generate an error, try something else. 
Compile time try-catch.  Look for the subject "static try catch 
construct would be helpful" in this newsgroup.  I still think that would 
be useful.

> I look at the examples and still think probably not. 

Yes, with those examples I agree with you.  They only use that Enable_if 
template which is easily replaced by a static if.

> The traits example can be solved cleanly in D, just like enable if. 

 > The toughest one is the vector 2 example. I think detection of what 
is a vector 2 could be done with an interface? The rest of the examples 
I read are SFINAE free.

Yes, well the vector2 one is the important one (but the parts that have 
to do with SFINAE aren't the problem). The traits templates can be 
thought of like compile-time adapters or facades.  So they are like 
compile-time interfaces in a way.  But they are non-intrusive.

Fred provides library Foo.
Barny provides type Bar.
Wilma wants to use Barny's Bar with Fred's Foo, but Fred and Barney 
designed their code separately and the interfaces are compatible.

So what traits templates do is give Fred's Foo a way to /ask Wilma/ what 
to do with Barney's Bar without having to get Barney involved.  Wilma 
provides a FooTraits!(T:Bar) specialization, and Fred's Foo instantiates 
it and uses that to find out what it needs to know. Of course this 
presumes Fred designed Foo with this sort of flexibility in mind.

Ok, so now that I've written all that out explicitly, I see that one 
nice but unessential thing about Traits as I've described them is that 
it operates in a "pull" manner.  That is, when Wilma tries to create a 
Foo!(Bar), Foo just turns around and tries to instantiate a 
FooTraits!(Bar), which could come from anywhere (in C++ anyway), and in 
this case it comes from Wilma's code.

So this can be worked around in D.  It just requires switching to a 
"push" model.  And that means the FooTraits must become an extra 
template parameter to Foo.  So instead of Wilma just instantiating a 
Foo!(Bar) with the traits automatically ferreted out internally as 
FooTraits!(Bar), Wilma will need to explicitly pass the traits, like 
Foo!(Bar, WilmasFooTraitsForBar).

So I guess it's not the end of the world.  I can't think of any reason 
off the top of my head that using the push model would be a show 
stopper.  It just isn't quite as slick.
I guess it makes things difficult for function templates though.  No 
IFTI if you have to provide a traits parameter explicitly.

--bb




More information about the Digitalmars-d mailing list