"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