RFR: 8251274: Provide utility types for function SFINAE using extra template parameters

Kim Barrett kim.barrett at oracle.com
Thu Aug 27 20:47:37 UTC 2020


> 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 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.




More information about the hotspot-dev mailing list