
1. Concepts and Variable Templates
Concepts (C++20) and variable templates (C++14) are both introduced in newer standards, so related technical standards may not immediately follow suit. In previous studies, we learned about functions that take other functions as parameters, known as higher-order functions. Similarly, in template programming, there are templates that take templates as parameters, which can also be referred to as higher-order templates. However, prior to C++26, template parameters for templates were restricted to class templates or alias templates, while concepts and variable templates were excluded from this.As we have continuously analyzed the evolution of standards, it becomes evident that the expansion and generalization of technology is an important development direction. In other words, applying concepts and variable templates to template parameters is an inevitable development. Furthermore, applying concepts and variable templates to template parameters will play a significant role in actual development, as it can reduce coding complexity and streamline related interfaces (for example, using different concepts for function overloads).Additionally, if variable templates are directly applied to template parameters, in some cases, object instantiation may no longer be necessary, significantly improving compilation speed, which is very important. This may not be common in ordinary programming, but it becomes crucial in metaprogramming. One could say that the generalization of template parameters is an inevitable outcome, although this path may take some time to traverse.
2. Both as Template Parameters
In the proposals for C++26, the application of both can be expressed as follows:
// Concepts
template<
template <template-parameter-list> concept C
>
// Variable Template
template<
template <template-parameter-list> auto C
>
This can be expanded to:
template<
typename T,
auto V,
template <template-parameter-list> typename TT,
template <template-parameter-list> auto VT,
template <template-parameter-list> concept C,
>
Similarly, in the above application, specific regulations regarding folding expressions and ADL (Argument Dependent Lookup) deduction have also been proposed. More specific details will need to wait for the final release of the C++26 standard.
3. Example
Let’s take a look at an example from the proposal:
// ADL
template <template <class> auto V, template <class> concept C>
struct A {}; // A accepts a variable template template argument
template <template <class T> auto V, template <class> concept C>
void foo(A<V, C>); // Can accept any specialization of A; V and C are deduced
template <class T>
auto Var = 0;
template <class T>
concept Concept = true;
void test() {
foo(A<Var, Concept>{});
}
// Partial ordering handling
template <template <typename T> concept X, typename T>
struct S {};
template <typename T>
concept A = true;
template <typename T>
concept B = true && A<T>;
template <typename T>
concept C = true && B<T>;
template <template <typename T> concept X, typename T>
int answer(S<X, T>) requires B<T> { return 42; } // #1
template <template <typename T> concept X, typename T>
int answer(S<X, T>) requires X<T> { return 43; } // #2
answer(S<A, int>{}); // ? #1 (B<int> checked) or #2 (A<int> checked)?
answer(S<C, int>{}); // ? #1 (B<int> checked) or #2 (C<int> checked)?
answer(S<B, int>{}); // ? #1 (B<int> checked) or #2 (B<int> checked)?
Note: Partial Ordering of templates refers to the priority rules for matching parameter types during template instantiation, used to resolve ambiguities in parameter type deduction.All the code above is from the proposal, and this section of code is heavily dependent on the implementation of the standard, so it will not be elaborated further. For those interested in the details, you can refer to the relevant documentation on cppreference and the related statements in the proposal.
4. Conclusion
The development of things is generally a gradual process, and it is rare to see a sudden change. The evolution of the C++ standard reflects this process; although the updates to the standard itself have entered a stable development phase, many technical details still require continuous refinement before they can be gradually perfected in future standards. There is no need to rush; we just need to wait and see.References: