RFR: 8251274: Provide utility types for function SFINAE using extra template parameters
Erik Österlund
erik.osterlund at oracle.com
Fri Aug 28 07:44:56 UTC 2020
Hi Kim,
On 2020-08-27 22:47, Kim Barrett wrote:
>> On Aug 27, 2020, at 5:10 AM, Erik Österlund <erik.osterlund at oracle.com> wrote:
>>
>> Hi Kim,
>>
>> On 2020-08-27 10:37, Kim Barrett wrote:
>>>> On Aug 27, 2020, at 4:24 AM, Erik Österlund <erik.osterlund at oracle.com> wrote:
>>>>
>>>> While I think having a legacy style that we are telling people not to use is unfortunate, I do understand that such a cleanup is a larger undertaking. So if the concern is that the identifier "EnableIf" is already taken today, then I think you can do what your previous example did: call the macro variant used inside of the template arguments ENABLE_IF instead, and have it take values only. Then we can transition away from using now "legacy" EnableIf gradually. And seeing as it is a macro, using capital letters is the natural name anyway.
>>> I think there’s a misunderstanding here.
>>>
>>> The failed (because of MSVC bugs) approach of an ENABLE_IF macro that accepts either a type
>>> or a constexpr value is just not on the table.
>>>
>>> What’s being proposed has zero macros; it’s all alias templates.
>>> I considered having macros in order to eliminate the trailing “= 0”, but that benefit didn’t seem to
>>> me to be worth (on it’s own) the issues that come with macros. (And remember that I like macros.)
>> Thank you for the clarification.
>>
>> So you said the approach of using ENABLE_IF macro that accepts either a type or constexpr value isn't on the table due to said compiler bugs. What was not and still is not clear to me is if the same bugs prevent an ENABLE_IF macro that accepts only a constexpr value. If that is also not on the table, then I see that we have a naming problem as long as the old legacy EnableIf is around. In other words - was the nature of the compiler problem that you can't use macros here at all, as opposed to being due to having to accept both types and values?
>>
>> I would appreciate clarification on that point in the problem domain before thinking further about the solution domain.
>>
>> Thanks,
>> /Erik
> That would work, as would a macro that takes a type. That is, both of
> these work.
>
> #define ENABLE_IF_T(...) EnableIfT<__VA_ARGS__> = 0
> #define ENABLE_IF_X(...) EnableIfX<__VA_ARGS__> = 0
>
> I didn't propose either of those because adding a macro just to eliminate
> the trailing " = 0" doesn't seem worthwhile.
I see. Yeah I can see how that might not feel worthwhile. Although in a way,
I guess the macro would hide the implementation details of the enable if
mechanism,
that otherwise leak out to the enable if user.
> I proposed both EnableIfT and EnableIfX because I don't think either alone
> is worthwhile, though for different reasons. (Assume that if we only had one
> that the T/X suffix would eventually be eliminated.) Both of them are
> basically about reducing syntactic noise.
>
> EnableIfT alone doesn't deal well with expressions, as the syntax to convert
> a value into a type is non-trivial. And I agree that expressions need to be
> well supported. The alternative to value => type conversion for expressions
> would be to use std::enable_if_t directly, but I think frequent switching in
> nearby code between EnableIf[T] and std::enable_if_t is undesirable.
>
> EnableIfX alone doesn't, in my opinion, carry its weight; just use
> std::enable_if_t directly. EnableIfX is just
>
> template<bool X> EnableIfX = std::enable_if_t<X, int>;
>
> Usage would be (for example)
>
> template<typename T, EnableIfX<std::is_integral<T>::value> = 0>
> void foo (T t) { ... }
>
> vs
>
> template<typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
> void foo (T t) { ... }
>
> I considered not proposing them at all. While I think together they provide
> enough to be worth having, I also think that's not blatantly clear and
> obvious. A single macro supporting both is much more compelling. If both
> were removed, I'm not sure what to do with EnableIfAnd/Or; retain in the
> proposal or retract the proposal entirely.
I once again understand that having just an alias type for std::enable_if_t
that takes an int might not feel worth while.
I can't believe I'm about to say this though, but what if you combine the
two not worthwhile things into that macro... it just might become worthwhile
combined (yes I think I am in favour of the macro while you are not - I
don't
know what is going on either!).
So if we don't do anything, the template parameter SFINAE syntax would
seemingly be:
template<typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
void foo (T t) { ... }
And if we have an ENABLE_IF macro that takes values only (keeping to the
convention
we have to work with values only as discussed previously), it would be:
template<typename T, ENABLE_IF(std::is_integral<T>::value)>
void foo (T t) { ... }
Here, I think I would actually prefer using the macro that hides the implementation
details how it works from the user, and in the API just focuses on only passing in
the right condition. Also, not importantly, the identifier ENABLE_IF is not taken
(while EnableIf is). That macro can also have some comments describing the trick
at one point, which I think is quite useful on its own.
I guess the macro itself would look like this:
#define ENABLE_IF(...) std::enable_if_t<__VA_ARGS__ , int> = 0
So this value SFINAE only macro for doing SFINAE using a template parameter seems like
something that we can actually do without relying on any compiler bugs being fixed or
refactoring the world in HotSpot (yet). And I think it is more readable than the return
type SFINAE we have today (that requires extra lines for the return type, and you have
to scratch your head to figure out what the actual return type is). I would say that
such a value SFINAE macro is worthwhile doing, IMO.
I tried it in my usecase I mentioned, and I think it looks pretty good. Feels like
having a nice comfortable sofa in the sewers. I think I want this nice comfortable sofa.
What do you think?
Thanks,
/Erik
More information about the hotspot-dev
mailing list