第一个简单的例子,不与GCC12编译:
#include <array>
#include <iostream>
#include <initializer_list>
template <int nvars> class Test1 {
public:
Test1( std::initializer_list<int> IL ) : arr { 0 }
{
// See https://stackoverflow.com/questions/38932089/can-i-initialize-an-array-using-the-stdinitializer-list-instead-of-brace-enclo
};
const std::array<int,nvars> arr;
};
// CTAD guide / simple-template-id
Test1(std::initializer_list<int> IL) -> Test1<IL.size()>;
int main() {
Test1 test1({1,2,3,4});
std::cout << "nvars: " << test1.arr.size() << std::endl;
}
这里的simple-template_id
是Test1<IL.size()>
,其中IL.size()
是返回4的constexpr
函数。它确实使用硬编码的4
进行编译,但这显然违背了目的。
CTAD指南simple-template_id
中允许和不允许的内容是什么?哪些名称,哪些类型的表达式?
问题像IL
这样的参数不是constexpr
。这意味着我们不能使用IL.size()
作为模板实参,因为模板实参必须是编译时常数。
N
、元素类型为T
的数组的引用,其中T
和N
都是模板形参。
template<typename T, std::size_t N> Test1(T const(&&)[N]) -> Test1<N>;