bloomberg/clang-p2996

Template splicers

Closed this issue · 4 comments

P2996 remains fairly vague on template splicers. But syntaxes like:

template <typename T>
consteval T fn(T value) { return value; }

constexpr auto R = ^fn;
static_assert(template [:R:](4) == 4);  // "template [:R:]" won't currently compile.

should presumably work.

As far as I know, this hasn't been implemented in any of the value-based reflection implementations. Some clarification may be needed in terms of the contexts in which they're allowed to appear (possibly this is better defined in P1240, but I haven't checked yet).

Contexts in which this is known to be needed:

  • Passing a splice of a template as a template-template argument
  • Forming a template-id for a specialization
  • CTAD, FTAD (including member function templates)
  • Type constraint on parameter declarations

Passing a splice of a template as a template-template argument now works. The other cases are yet to be implemented.

Another case for template splicers which we had not previously considered: Use as a type constraint in a function declaration (example here).

Several uses of template splicers have now been implemented:

  • Use as a template argument (e.g., fn<[:R:]>(), fn<template [:R:]>())
  • Forming template IDs (e.g., typename [:^std::vector:]<int> vec;)
  • FTAD (e.g., template [:^TemplateFn:](3)

The remaining behaviors are:

  • CTAD
  • Use in a type constraint
  • Use of template decorator when the reflection is of a class template or type alias template(e.g., template [:^std::vector:]<int> vec;).

I think it will be more useful to track this remaining work separately, so I'll close this issue now and open additional ones of smaller scope.