Open mpusz opened 1 year ago
See the R1 draft with some updates (definitely not ready) here: https://github.com/mpusz/wg21-papers/blob/master/src/2008R1_enable_variable_template_template_parameters.md
@mhermier might have an implementation experience with this proposal?
I still have my preliminary work available, that was not updated since last year on llvm compiler. I will try to rebase the git and review the patchset to see how much it differ from the draft.
Great :-) Please note that the P2008 was merged into the proposal in this repo.
Interesting quote about the implementability: https://lists.isocpp.org/ext/2017/02/1910.php
Besides the ones mentioned in R1 draft, here are the use cases that I gathered so far:
std::numbers::pi_v
as a template parameter
passing ratio<Rep>
as an NTTP (not std::ratio
)
@camaclean provided a PR https://github.com/mpusz/wg21-papers/pull/19 but we never had time to finalize it and merge with the main proposal
Additionaly, @lichray had some doubts about its implementability:
This idea looks interesting at a first glance,
template<typename R, typename... Args>
auto foo_os = static_cast<R(*)(Args...)>(&foo);
but I don't think it can work, because its call site is
func(args...)
. Conversion and deduction do not work at the same time in C++.The use case I found suggests a simple interpretation: if there is a
template<class T1, class T2>
void foo(T1, T2);
you can pass foo to a template
auto parameter as if passing
template<class T1, class T2>
inline auto& foo_os = foo<T1, T2>;
The deduction works as if there is a deduction guide for selecting variable template specialization
template<class T1, class T2>
foo_os(T1, T2) -> foo_os<T1, T2>;
Or you can say this is just the function template foo itself.
The template parameter list of the imaginary variable template is identical to the source function template, so there might be non-type template parameters and
template<class...>
auto doesn't match. But this can be addressed by other papers.
example from @mhermier:
At some point I reached some template meta programing where I count the number of types of a template class. Naturally at some point I wanted to implement a template conditional count, to check that some types match some criterias. Given my original goal, and given all the available templates variables (also available std) I tried:
template <class T, template <class> bool UnaryPredicate>
inline constexpr bool type_list_count_if = detail::type_list_count<T, UnaryPredicate>::value;
and another one from @mhermier:
template <class T, template <class> bool... UnaryPredicates>
inline constexpr bool match = /* implementation details */;
match<MyType, std::is_class_v, std::is_final_v>
although I am not sure if it can defend against:
template <class T, template <class> class... UnaryPredicates>
inline constexpr bool match = std::conjunction_v<UnaryPredicates<T>...>;
match<MyType, std::is_class, std::is_final>
@lichray shared such a problem: https://reviews.llvm.org/D118551
I cannot do better than a macro.
The problem here is that the language doesn't allow you to pass any thing whose specializations are expressions. Richard Smith's extension perfectly solves that problem: https://lists.isocpp.org/ext/2017/02/1914.php
Not only function templates. Because captureless closures are also structural types, things like this
template<class T>
inline constexpr auto fn = [](auto ...args) { any_runtime_work(); };
can also be passed as template parameters. But this time, we can pass the a "closure template". This workarounds the difficulty of passing overloaded function templates.
Is the name name variable template parameter kind
final? It feels a little bit odd to me.
'variable template template parameter kind' would be more logical to me as it is a 'variable template' as a 'template parameter'.
edit: After reading [13.2] it seems the correct naming would be variable-parameter
P2008R0 was accepted by EWGI and forwarded to EWG at the last F2F meeting in Prague. I was only asked to provide more good motivating examples.