c++26新功能—模板参数中的概念与变量模板
一、概念和变量模板
概念(C++20)和变量模板(C++14)都是较新的标准中提出来的,所以相关的一些技术标准则不会立刻的跟进上来。在前面的学习中,学习过把函数做为函数参数的函数,它们被称为高阶函数。而在模板编程的学习中,也有以模板做为模板参数的模板,当然也可以称为高阶模板。但在C++26前,模板的模板参数,被限制为类模板或别名模板,而概念和变量模板则被限制在之外。
正如前面不断分析和看到的标准的演进,会发现,技术的扩大和泛化,是一个重要的发展方向。也就是说,把概念和变量模板应用到模板参数中,是一种发展的必然。另外,把概念和变量模板应用到模板参数中,对于在实际的开发中,也会起到重要的作用。同时,它还可以降低一些编码的复杂度和精简(比如一些函数接口使用了不同的概念做为重载等)相关的接口。
另外,变量模板如果直接应用到模板参数中,在有些情况下可以不再实例化对象,可以大幅的提高相关的编译速度,这一点非常重要。这一点在普通编程中可能场景不多,但在元编程中,可能就非常重要了。或者可以这样说,模板参数的泛化,是一种必然的结果。只是,这条路需要走的长一些。
二、二者作为模板参数
在C++26中的提案中,对二者的应用可以用下面的方式进行表达:
//概念
template<template <template-parameter-list> concept C
>
//变量模板
template<template <template-parameter-list> auto C
>
即可以扩展为:
template<typename T,auto V,template <template-parameter-list> typename TT,template <template-parameter-list> auto VT,template <template-parameter-list> concept C,
>
同样,在上面的应用中,也提出了针对参数中的折叠表达式以及ADL推导等的具体规定。更具体的细节需要等待最终的C++26标准的推出为准。
三、例程
看一下提案中的例程:
//ADL
template <template <class> auto V, template <class> concept C>
struct A {}; // A 接受一个变量模板模板实参template <template <class T> auto V, template <class> concept C>
void foo(A<V, C>); // 可以接受 A 的任何特化;V 和 C 被推导template <class T>
auto Var = 0;template <class T>
concept Concept = true;void test() {foo(A<Var, Concept>{});
}
//偏序的处理
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; } // #2answer(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)?
说明:模板的偏序(Partial Ordering):指模板实例化过程中参数类型匹配的优先级规则,用于解决参数类型推导的歧义问题。
上面的代码都是提案中的代码,这一块的代码强依赖于标准的实现,所以这一块不展开。如果对细节有兴趣的,可以参看cppreference上的相关文档及提案的相关表述说明。
四、总结
事物的发展都是有一个渐进的过程的,基本上很难出现一蹴而就的情况。C++的标准的发展也恰恰体现了这个过程,虽然标准本身的更迭已经进入了稳定的发展状态,但很多的技术细节仍然需要不断的打磨,才可能在后续的新标准中渐渐得到完善。大家不用着急,只需拭目以待。