digitalmars.D - "SFINAE is Evil"
- Jason House (13/13) Mar 20 2008 SFINAE - Substitution failure is not an error
- Craig Black (8/23) Mar 20 2008 I get the feeling that a number of features in D can eventually be dumpe...
- Bill Baxter (14/30) Mar 20 2008 How do I know if I'm using SFINAE or not? :-)
- Russell Lewis (6/16) Mar 21 2008 Tuples hurt you here, because if you specify some Tuple template as a
- Russell Lewis (24/28) Mar 21 2008 Here's a classic example of how SFINAE makes things hard. Look at the
- Jason House (1/37) Mar 21 2008
- Russell Lewis (36/37) Mar 24 2008 function.
- Jason House (4/20) Mar 21 2008 I should probably expand this question...
- Bill Baxter (16/21) Mar 22 2008 I don't have time to write more right now, but
- Jason House (2/30) Mar 22 2008
- Bill Baxter (5/5) Mar 22 2008 I was looking around for something good on traits templates, the hows
- Bill Baxter (7/7) Mar 22 2008 The description of traits in Boost is quite succinct and hits the good
- Jason House (2/11) Mar 22 2008 If D could load specializations in another module, generalized traits co...
- Bill Baxter (50/65) Mar 23 2008 static if as needed for specialization. I don't forsee more complex
- Jason House (14/27) Mar 24 2008 I also had the feeling of "SFINAE is needed, but I can't come up with an...
- Georg Wrede (6/21) Mar 25 2008 I suspect it would be quite simple to add a compiler switch to turn
- Bill Baxter (7/33) Mar 25 2008 That would be great. I'd love to try out such a switch. Though at the
- Jarrett Billingsley (8/13) Mar 25 2008 Great idea!
- Jason House (2/9) Mar 25 2008 That about sums it up :(
- Bill Baxter (4/15) Mar 25 2008 Yes, sweet. Someone should post a self-referential url in this thread
- Jason House (6/23) Mar 26 2008 I created an enhancement request (#1951) for this. That should (hopeful...
- Bruno Medeiros (7/15) Mar 26 2008 Upon reading that, it's amazing how much more simple(and powerful)
- Christopher Wright (35/39) Mar 22 2008 Templates are utterly necessary and horribly untestable. I use them, but...
- Jason House (2/51) Mar 22 2008
- Christopher Wright (2/3) Mar 22 2008 Yes, and I wish I could do without templates.
- Georg Wrede (6/11) Mar 25 2008 I don't need templates. But that's probably because I only do apps. If I...
SFINAE - Substitution failure is not an error This post is all about templates and their static if counterparts. With the enhanced expressiveness of D, is there a need for SFINAE from C++? Essentially, when a specialization exists, if the compilation of the specialization fails, the compiler silently gives up on it and goes to the next more general case. In my mind, this is both dangerous and a loop hole for long compile times (as the compiler instantiates extra template instances). What I want to know is this: Who uses SFINAE in D, and why? Is this a matter of convenience or a requirement. If required, I assume it's from a lack of expressiveness in defining a template's conditions. Could this be overcome with use of static if's instead? PS: Post title is a quote of Russell Lewis from another thread.
Mar 20 2008
"Jason House" <jason.james.house gmail.com> wrote in message news:frv6ut$2ecv$1 digitalmars.com...SFINAE - Substitution failure is not an error This post is all about templates and their static if counterparts. With the enhanced expressiveness of D, is there a need for SFINAE from C++? Essentially, when a specialization exists, if the compilation of the specialization fails, the compiler silently gives up on it and goes to the next more general case. In my mind, this is both dangerous and a loop hole for long compile times (as the compiler instantiates extra template instances). What I want to know is this: Who uses SFINAE in D, and why? Is this a matter of convenience or a requirement. If required, I assume it's from a lack of expressiveness in defining a template's conditions. Could this be overcome with use of static if's instead? PS: Post title is a quote of Russell Lewis from another thread.I get the feeling that a number of features in D can eventually be dumped in favor of others. Perhaps SFINAE is one of them. I haven't used templates in D enough to know for sure. Definitely worth discussing though IMO. Anything that reduces the complexity of D without sacrificing expressive power is a good thing. -Craig
Mar 20 2008
Jason House wrote:SFINAE - Substitution failure is not an error This post is all about templates and their static if counterparts. With the enhanced expressiveness of D, is there a need for SFINAE from C++? Essentially, when a specialization exists, if the compilation of the specialization fails, the compiler silently gives up on it and goes to the next more general case. In my mind, this is both dangerous and a loop hole for long compile times (as the compiler instantiates extra template instances). What I want to know is this: Who uses SFINAE in D, and why? Is this a matter of convenience or a requirement. If required, I assume it's from a lack of expressiveness in defining a template's conditions. Could this be overcome with use of static if's instead? PS: Post title is a quote of Russell Lewis from another thread.How do I know if I'm using SFINAE or not? :-) Seriously, I might be using it. I'm not sure. I'm not sure how to go about checking. And that in and of itself seems like an undesirable quality. I will say that I have most definitely been bitten by errors that came from failure to instantiate the template I thought I was instantiating (most often due to IFTI failures). These things can usually be debugged by switching the code I suspect to specify all template arguments. Then I'll get the sensible error telling me why it doesn't match. Also I've had bugs from the is-expressions not getting triggered because I had a typo in the is-expression which wasn't a syntax error. Not sure how the compiler could help there, though. --bb
Mar 20 2008
Bill Baxter wrote:How do I know if I'm using SFINAE or not? :-) Seriously, I might be using it. I'm not sure. I'm not sure how to go about checking. And that in and of itself seems like an undesirable quality.Indeed!I will say that I have most definitely been bitten by errors that came from failure to instantiate the template I thought I was instantiating (most often due to IFTI failures). These things can usually be debugged by switching the code I suspect to specify all template arguments. Then I'll get the sensible error telling me why it doesn't match.Tuples hurt you here, because if you specify some Tuple template as a "last resort" template, you can end up using it for things you thought you'd handled. Or, at least, I think that maybe that's the case...with SFINAE, it's hard to know for sure.
Mar 21 2008
Jason House wrote:SFINAE - Substitution failure is not an error This post is all about templates and their static if counterparts. With the enhanced expressiveness of D, is there a need for SFINAE from C++?Here's a classic example of how SFINAE makes things hard. Look at the code below. You'd expect the static assert to fail, right? Give you an error message at the right location, and point you towards your bug? Nope. BEGIN CODE import std.stdio; template foo(TPL...) { static assert(false); } void main() { int i; foo!(i)(); } END CODE Here's what the compiler actually says: sfinae.d(3): template sfinae.foo(TPL...) is not a function template sfinae.d(11): template sfinae.foo(TPL...) cannot deduce template function from argument types !(i)() Not even a mention of the real problem. Now imagine that you are using non-trivial templates! Russ
Mar 21 2008
It looks like your first compiler error is correct... There is no function.Jason House wrote:SFINAE - Substitution failure is not an error This post is all about templates and their static if counterparts. With the enhanced expressiveness of D, is there a need for SFINAE from C++?Here's a classic example of how SFINAE makes things hard. Look at the code below. You'd expect the static assert to fail, right? Give you an error message at the right location, and point you towards your bug? Nope. BEGIN CODE import std.stdio; template foo(TPL...) { static assert(false); } void main() { int i; foo!(i)(); } END CODE Here's what the compiler actually says: sfinae.d(3): template sfinae.foo(TPL...) is not a function template sfinae.d(11): template sfinae.foo(TPL...) cannot deduce template function from argument types !(i)() Not even a mention of the real problem. Now imagine that you are using non-trivial templates! Russ
Mar 21 2008
Jason House wrote:It looks like your first compiler error is correct... There is nofunction. You were right. I've seen that error so many times before, in cases, where a function did exist, that I didn't look closely enough. Here's a better example. The following code will produce useless "not a function template errors." Obviously, if you comment out the "static assert(false);", it works just fine. BEGIN dmd OUTPUT sfinae.d(3): template sfinae.foo(int I) is not a function template sfinae.d(22): template sfinae.foo(int I) cannot deduce template function from argument types !(5)() END OUTPUT BEGIN CODE import std.stdio; template foo(int I) { static if(I == 1) { void foo() {}; } else { void foo() { static assert(false); foo!(1)(); foo!(I-1)(); } } } void main() { foo!(5)(); } END CODE
Mar 24 2008
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. Jason House Wrote:SFINAE - Substitution failure is not an error This post is all about templates and their static if counterparts. With the enhanced expressiveness of D, is there a need for SFINAE from C++? Essentially, when a specialization exists, if the compilation of the specialization fails, the compiler silently gives up on it and goes to the next more general case. In my mind, this is both dangerous and a loop hole for long compile times (as the compiler instantiates extra template instances). What I want to know is this: Who uses SFINAE in D, and why? Is this a matter of convenience or a requirement. If required, I assume it's from a lack of expressiveness in defining a template's conditions. Could this be overcome with use of static if's instead? PS: Post title is a quote of Russell Lewis from another thread.
Mar 21 2008
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 Certainly the Enable_if template can be replaced by a simple static if. Maybe the other one too. The main problem I have with templates in D is that traits templates are severely limited by the inability to define specializations for a template in different modules. Like the IsVector_2 template Lutz talks about. If all specializations have to be in one file, then the library designer has to know in advance all the types that can ever be used as a Vector2 and clearly that limits the utility of it. Maybe this is coming in D2. I think I did a test recently and it still didn't work. --bb
Mar 22 2008
I look forward to when you can write more... Are you trying to say SFINAE is needed? I look at the examples and still think probably not. 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 reaf are SFINAE free. 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 Certainly the Enable_if template can be replaced by a simple static if. Maybe the other one too. The main problem I have with templates in D is that traits templates are severely limited by the inability to define specializations for a template in different modules. Like the IsVector_2 template Lutz talks about. If all specializations have to be in one file, then the library designer has to know in advance all the types that can ever be used as a Vector2 and clearly that limits the utility of it. Maybe this is coming in D2. I think I did a test recently and it still didn't work. --bb
Mar 22 2008
I was looking around for something good on traits templates, the hows and whys. This seems to be pretty decent: http://www.cantrip.org/traits.html --bb
Mar 22 2008
The description of traits in Boost is quite succinct and hits the good points -- particularly about the non-intrusive part: http://www.boost.org/more/generic_programming.html#traits I think most traits-like things can be done in D if you require that people modify their classes. But the non-intrusiveness is one of key parts of what makes traits templates a good building block. --bb
Mar 22 2008
Bill Baxter Wrote:The description of traits in Boost is quite succinct and hits the good points -- particularly about the non-intrusive part: http://www.boost.org/more/generic_programming.html#traits I think most traits-like things can be done in D if you require that people modify their classes. But the non-intrusiveness is one of key parts of what makes traits templates a good building block. --bbIf D could load specializations in another module, generalized traits could be done in D. In fact, I'd argue that SFINAE would hide bugs in user-supplied template code.
Mar 22 2008
Bill Baxter Wrote:Do you ever plan to get more complex? Would SFINAE make your life easier or harder?Jason House wrote:I should probably expand this question... Who uses templates in D? What is the most complex use you've done?static if as needed for specialization. I don't forsee more complex usage and view SFINAE as something that would mask bugs.I've written templates classes that have one definition, and usedhttp://www.mpi-inf.mpg.de/~kettner/courses/lib_design_03/notes/meta.html#ConstrainingI 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#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 whatis 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
Mar 23 2008
Bill Baxter wrote:Jason House wrote:I also had the feeling of "SFINAE is needed, but I can't come up with any examples". I find it interesting that nobody posted a need for SFINAE. Because of that, and all the pitfalls, I agree that SFINAE as a default behavior is undesirable and should disapear from D. Rather than propose an alternative to it, I wanted to understand how it should be used in D. With no examples of it, I've started leaning toward simple removal of it. I started this thread thinking the likely outcome would be something like your proposal. Now I'm thinking that SFINAE is not needed. If that's not true, I'm thinking it may be better to enhance is clauses and/or CTFE to cover the (small) capability gap. What do you think of that? If you (and others paying attention to this thread) agree, how do we get the attention of Walter? Maybe it should be a feature request or an entry on the unofficial D wishlist?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.
Mar 24 2008
Jason House wrote:I also had the feeling of "SFINAE is needed, but I can't come up with any examples". I find it interesting that nobody posted a need for SFINAE. Because of that, and all the pitfalls, I agree that SFINAE as a default behavior is undesirable and should disapear from D. Rather than propose an alternative to it, I wanted to understand how it should be used in D. With no examples of it, I've started leaning toward simple removal of it. I started this thread thinking the likely outcome would be something like your proposal. Now I'm thinking that SFINAE is not needed. If that's not true, I'm thinking it may be better to enhance is clauses and/or CTFE to cover the (small) capability gap. What do you think of that? If you (and others paying attention to this thread) agree, how do we get the attention of Walter? Maybe it should be a feature request or an entry on the unofficial D wishlist?I suspect it would be quite simple to add a compiler switch to turn SFINAE on or off? Since D2 is "experimental" anyway, we might have this switch for a few months, and then see if anybody actually used it. The default would be SF is an error.
Mar 25 2008
Georg Wrede wrote:Jason House wrote:That would be great. I'd love to try out such a switch. Though at the moment it would do me no good unless it were added to D1 also. Though rather than turning it off, I'd rather have a -v kind of switch that prints out a message whenever SFINAE is invoked, maybe with an instantiation stack trace. --bbI also had the feeling of "SFINAE is needed, but I can't come up with any examples". I find it interesting that nobody posted a need for SFINAE. Because of that, and all the pitfalls, I agree that SFINAE as a default behavior is undesirable and should disapear from D. Rather than propose an alternative to it, I wanted to understand how it should be used in D. With no examples of it, I've started leaning toward simple removal of it. I started this thread thinking the likely outcome would be something like your proposal. Now I'm thinking that SFINAE is not needed. If that's not true, I'm thinking it may be better to enhance is clauses and/or CTFE to cover the (small) capability gap. What do you think of that? If you (and others paying attention to this thread) agree, how do we get the attention of Walter? Maybe it should be a feature request or an entry on the unofficial D wishlist?I suspect it would be quite simple to add a compiler switch to turn SFINAE on or off? Since D2 is "experimental" anyway, we might have this switch for a few months, and then see if anybody actually used it. The default would be SF is an error.
Mar 25 2008
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fsbp54$293h$1 digitalmars.com...That would be great. I'd love to try out such a switch. Though at the moment it would do me no good unless it were added to D1 also. Though rather than turning it off, I'd rather have a -v kind of switch that prints out a message whenever SFINAE is invoked, maybe with an instantiation stack trace.Great idea! <narrator>And with that, the suggestion began its slow, painful descent into the depths of the unread old posts of the NG, never to be seen again or commented on by the very man who could make a difference. Months later many would reminisce about what a good idea it was, and would sigh nostalgically over their youthful optimism.</narrator>
Mar 25 2008
Jarrett Billingsley wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message <narrator>And with that, the suggestion began its slow, painful descent into the depths of the unread old posts of the NG, never to be seen again or commented on by the very man who could make a difference. Months later many would reminisce about what a good idea it was, and would sigh nostalgically over their youthful optimism.</narrator>That about sums it up :(
Mar 25 2008
Jason House wrote:Jarrett Billingsley wrote:Yes, sweet. Someone should post a self-referential url in this thread so it will be easier to find and refer to it later. :-) --bb"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message <narrator>And with that, the suggestion began its slow, painful descent into the depths of the unread old posts of the NG, never to be seen again or commented on by the very man who could make a difference. Months later many would reminisce about what a good idea it was, and would sigh nostalgically over their youthful optimism.</narrator>That about sums it up :(
Mar 25 2008
Jarrett Billingsley wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:fsbp54$293h$1 digitalmars.com...gain visibility with Walter (and more importantly?) Andrei, who's been known to fully flex C++'s templates. Feel free to add individual ideas on what might be a good alternative to SFINAE. I really didn't put any in the enhancement request.That would be great. I'd love to try out such a switch. Though at the moment it would do me no good unless it were added to D1 also. Though rather than turning it off, I'd rather have a -v kind of switch that prints out a message whenever SFINAE is invoked, maybe with an instantiation stack trace.Great idea! <narrator>And with that, the suggestion began its slow, painful descent into the depths of the unread old posts of the NG, never to be seen again or commented on by the very man who could make a difference. Months later many would reminisce about what a good idea it was, and would sigh nostalgically over their youthful optimism.</narrator>
Mar 26 2008
Bill Baxter wrote: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/me a.html#Constraining http://www.mpi-inf.mpg.de/~kettner/courses/lib_design_03/notes/meta html#ClassificationUpon reading that, it's amazing how much more simple(and powerful) meta-programming is in D. (having static if, is-expressions, aliases, and D template syntax) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Mar 26 2008
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?Templates are utterly necessary and horribly untestable. I use them, but I try to keep them as braindead simple as possible. I've done a reasonable amount of work with simple templates, eg DUnit's assertions, and some slightly more complex stuff, as with DMocks, but nothing incredibly difficult. DMocks was mainly a matter of looping through reflection information and assembling some strings based on that, which wasn't so difficult; the hardest thing (besides debugging CTFE failures and oddities with mixins, but I did my best to limit the amount of both) was not being able to have a variable whose type was an empty tuple. I had to wrap the tuple in a templated class that would just not instantiate the arguments variable with an empty tuple. SFINAE isn't a problem for me -- I don't need to overload templates much. If I did, I'd do it like this: template Foo(T, U, V...) { static if (condition1) { alias FooSpecialization1!(T, U, V) Foo; } else // ... } The only thing the compiler could do to help me that it isn't doing is to make it an error to have overloaded templates.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.Same. The only issue is with templates from different modules or libraries. In this case, it could be helpful for the compiler to have an error message along the lines of: template instantiation Foo!(int, float, float, char[]): could not instantiate. Candidates are: valhalla.odin.Foo(T : long, U, T, V[char]) : char[] is not a V[char] valhalla.thor.Foo(T : class, U...) : int is not a class ...
Mar 22 2008
Ok, so you're saying you could do without SFINAE? Christopher Wright 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?Templates are utterly necessary and horribly untestable. I use them, but I try to keep them as braindead simple as possible. I've done a reasonable amount of work with simple templates, eg DUnit's assertions, and some slightly more complex stuff, as with DMocks, but nothing incredibly difficult. DMocks was mainly a matter of looping through reflection information and assembling some strings based on that, which wasn't so difficult; the hardest thing (besides debugging CTFE failures and oddities with mixins, but I did my best to limit the amount of both) was not being able to have a variable whose type was an empty tuple. I had to wrap the tuple in a templated class that would just not instantiate the arguments variable with an empty tuple. SFINAE isn't a problem for me -- I don't need to overload templates much. If I did, I'd do it like this: template Foo(T, U, V...) { static if (condition1) { alias FooSpecialization1!(T, U, V) Foo; } else // ... } The only thing the compiler could do to help me that it isn't doing is to make it an error to have overloaded templates.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.Same. The only issue is with templates from different modules or libraries. In this case, it could be helpful for the compiler to have an error message along the lines of: template instantiation Foo!(int, float, float, char[]): could not instantiate. Candidates are: valhalla.odin.Foo(T : long, U, T, V[char]) : char[] is not a V[char] valhalla.thor.Foo(T : class, U...) : int is not a class ...
Mar 22 2008
Jason House wrote:Ok, so you're saying you could do without SFINAE?Yes, and I wish I could do without templates.
Mar 22 2008
Christopher Wright wrote:Jason House wrote:I don't need templates. But that's probably because I only do apps. If I were to write libraries (even for myself), then I'd expect to be using templates in many, if not most of the functions. I's just that I currently don't run into things where I'd need a template. As for SFINAE, I can't even imagine where I'd gain with it.Ok, so you're saying you could do without SFINAE?Yes, and I wish I could do without templates.
Mar 25 2008