> On Aug 23, 2017, at 12:21 PM, Konstantin Tokarev <[email protected]> wrote:
> 
> 
> 
> 23.08.2017, 21:15, "Keith Miller" <[email protected] 
> <mailto:[email protected]>>:
>> You can totally have the enable_if in the template list:
>> 
>> #define ENABLE_TEMPLATE_IF(condition) typename = typename 
>> std::enable_if<condition>::type
>> 
>> template<typename T, ENABLE_TEMPLATE_IF((std::is_same<T, int>::value))>
>> int foo() { return 0; }
>> 
>> template<typename T, ENABLE_TEMPLATE_IF((std::is_same<T, double>::value))>
>> double foo() { return 0; }
>> 
>> int myFunction()
>> {
>>     return foo<int>();
>> }
>> 
>> Compiles fine for me.
>> 
>> There is another downside to the macros though. Since they will probably 
>> have a comma in them C++ thinks that comma is meant to distinguish arguments 
>> to the macro... The only work around I know of is to wrap the argument in 
>> parens as I did above.
> 
> Actually, you need no parens:
> 
> #define ENABLE_TEMPLATE_IF(...) typename = typename 
> std::enable_if<__VA_ARGS__>::type
> 
> template<typename T, ENABLE_TEMPLATE_IF(std::is_same<T, int>::value)>
> int foo() { return 0; }
> 
> template<typename T, ENABLE_TEMPLATE_IF(std::is_same<T, double>::value)>
> double foo() { return 0; }
> 
> int myFunction()
> {
>     return foo<int>();
> }

Oh, clever! I didn’t think of that.

> 
> 
>> 
>> I think mark’s case doesn’t work with my proposal so that’s convinced me 
>> that the template argument is the way to go. Although, I still think we 
>> should use the macro.
>> 
>> Any objections?
>> 
>> Cheers,
>> Keith
>> 
>>>  On Aug 23, 2017, at 7:28 AM, Mark Lam <[email protected]> wrote:
>>> 
>>>  One application of enable_if I’ve needed in the past is where I want 
>>> specialization of a template function with the same argument signatures, 
>>> but returning a different type. The only way I know to make that happen is 
>>> to use enable_if in the return type, e.g.
>>> 
>>>      std::enable_if<std::is_integral<T>, T>::type doStuff() { }
>>>      std::enable_if<std::is_double<T>, T>::type doStuff() { }
>>> 
>>>  This works around the problem of “duplicate function definitions” which 
>>> arises if the enable_if is not in the function signature itself. So, I’m 
>>> not sure your ENABLE_TEMPLATE_IF macro will give me a solution for this.
>>> 
>>>  Mark
>>> 
>>>>  On Aug 22, 2017, at 11:14 PM, Keith Miller <[email protected]> wrote:
>>>> 
>>>>>  On Aug 22, 2017, at 9:17 PM, JF Bastien <[email protected]> wrote:
>>>>> 
>>>>>  I'd suggest considering what it'll look like when we're migrating to 
>>>>> concepts in C++20.
>>>>> 
>>>>>  Here's an example for our bitwise_cast:
>>>>>  https://github.com/jfbastien/bit_cast/blob/master/bit_cast.h#L10
>>>>> 
>>>>>  Notice the 3 ways to enable. There's also the option of using enable_if 
>>>>> on the return value, or as a defaulted function parameter, but I'm not a 
>>>>> huge fan of either.
>>>> 
>>>>  I think the concepts approach is the cleanest. I’d avoid the macro if we 
>>>> go that way.
>>>> 
>>>>  But C++20 is a long way away and I only expect this problem to get worse 
>>>> over time. So I’d rather find a nearer term solution.
>>>> 
>>>>>  On Aug 22, 2017, at 9:13 PM, Chris Dumez <[email protected]> wrote:
>>>>> 
>>>>>  I personally prefer std::enable_if<>. For e.g.
>>>>> 
>>>>>  template<typename T, class = typename std::enable_if<std::is_same<T, 
>>>>> int>::value>
>>>>>  Class Foo { }
>>>> 
>>>>  I just find this much harder to parse since I now have to:
>>>> 
>>>>  1) recognize that the last class is not a actually polymorphic parameter
>>>>  2) figure out exactly what the condition is given that it’s hidden inside 
>>>> an enable_if*
>>>> 
>>>>  The plus side of using a static_assert based approach is that it doesn’t 
>>>> impact the readability of function/class signature at a high level since 
>>>> it’s nested inside the body. It’s also not hidden particularly hidden 
>>>> since I would expect it to be the first line of the body
>>>> 
>>>>  Another downside of enable_if as a default template parameter is that 
>>>> someone could make a mistake and pass an extra template value, e.g. 
>>>> Foo<float, int>, and it might pick the wrong template parameter. This 
>>>> isn’t super likely but it’s still a hazard.
>>>> 
>>>>  Admittedly, we could make a macro like (totes not stolen from JF’s 
>>>> GitHub):
>>>> 
>>>>  #define ENABLE_TEMPLATE_IF(condition) typename = typename 
>>>> std::enable_if<condition>::type
>>>> 
>>>>  and implement Foo as:
>>>> 
>>>>  template<typename T, ENABLE_TEMPLATE_IF(std::is_same<T, int>::value)>
>>>>  class Foo { };
>>>> 
>>>>  I think this approach is pretty good, although, I think I care about the 
>>>> enable_if condition rarely enough that I’d rather not see it in the 
>>>> signature. Most of the time the code will look like:
>>>> 
>>>>  template<typename T, ENABLE_TEMPLATE_IF(std::is_same<T, int>::value)>
>>>>  class Foo {...};
>>>> 
>>>>  template<typename T, ENABLE_TEMPLATE_IF(std::is_same<T, float>::value)>
>>>>  class Foo {...};
>>>> 
>>>>  template<typename T, ENABLE_TEMPLATE_IF(std::is_same<T, double>::value)>
>>>>  class Foo {...};
>>>> 
>>>>  So when I know I want to use a Foo but I forgot the signature I now need 
>>>> to look mentally skip the enable_if macro, which I’d rather avoid.
>>>> 
>>>>>  I don’t like that something inside the body of a class / function would 
>>>>> cause a template to be enabled or not.
>>>> 
>>>>  I believe there are cases where this already basically already happens 
>>>> e.g. bitwise_cast. Although, I think those cases could be fixed with a 
>>>> more standard approach.
>>>> 
>>>>  Cheers,
>>>>  Keith
>>>> 
>>>>>  --
>>>>>   Chris Dumez
>>>>> 
>>>>>>  On Aug 22, 2017, at 8:34 PM, Keith Miller <[email protected]> 
>>>>>> wrote:
>>>>>> 
>>>>>>  Hello fellow WebKittens,
>>>>>> 
>>>>>>  I’ve noticed over time that we don’t have standard way that we enable 
>>>>>> versions of template functions/classes (flasses?). For the most part it 
>>>>>> seems that people use std::enable_if, although, it seems like it is 
>>>>>> attached to every possible place in the function/class.
>>>>>> 
>>>>>>  I propose that we choose a standard way to conditionally enable a 
>>>>>> template.
>>>>>> 
>>>>>>  There are a ton of options; my personal favorite is to add the 
>>>>>> following macro:
>>>>>> 
>>>>>>  #define ENABLE_TEMPLATE_IF(condition) static_assert(condition, 
>>>>>> “template disabled”)
>>>>>> 
>>>>>>  Then have every function do:
>>>>>> 
>>>>>>  template<typename T>
>>>>>>  void foo(…)
>>>>>>  {
>>>>>>     ENABLE_TEMPLATE_IF(std::is_same<T, int>::value);
>>>>>>     …
>>>>>>  }
>>>>>> 
>>>>>>  And classes:
>>>>>> 
>>>>>>  template<typename T>
>>>>>>  class Foo {
>>>>>>     ENABLE_TEMPLATE_IF(std::is_same<T, int>::value);
>>>>>>  };
>>>>>> 
>>>>>>  I like this proposal because it doesn’t obstruct the 
>>>>>> signature/declaration of the function/class but it’s still obvious when 
>>>>>> the class is enabled. Obviously, I think we should require that this 
>>>>>> macro is the first line of the function or class for visibility. Does 
>>>>>> anyone else have thoughts or ideas?
>>>>>> 
>>>>>>  Cheers,
>>>>>>  Keith
>>>>>> 
>>>>>>  P.S. in case you are wondering why this macro works (ugh C++), it’s 
>>>>>> because if there is any compile time error in a template it cannot be 
>>>>>> selected as the final candidate. In my examples, if you provided a type 
>>>>>> other than int foo/Foo could not be selected because the static_assert 
>>>>>> condition would be false, which is a compile error.
>>>>>>  _______________________________________________
>>>>>>  webkit-dev mailing list
>>>>>>  [email protected]
>>>>>>  https://lists.webkit.org/mailman/listinfo/webkit-dev
>>>> 
>>>>  _______________________________________________
>>>>  webkit-dev mailing list
>>>>  [email protected]
>>>>  https://lists.webkit.org/mailman/listinfo/webkit-dev
>> 
>> _______________________________________________
>> webkit-dev mailing list
>> [email protected]
>> https://lists.webkit.org/mailman/listinfo/webkit-dev
> 
> -- 
> Regards,
> Konstantin

_______________________________________________
webkit-dev mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-dev

Reply via email to