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]
>> <mailto:[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
>> <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]
>> <mailto:[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]
>>> <mailto:[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] <mailto:[email protected]>
>>> https://lists.webkit.org/mailman/listinfo/webkit-dev
>>> <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