我在https://stackoverflow.com/a/36132696/3206356找到了一个代码,我试了一下。它有效,但我不完全理解那里发生的事情。
我从下面的链接重复了代码:
template <size_t N, class = std::make_index_sequence<N>>
class Vector;
template <size_t N, size_t... Is>
class Vector<N, std::index_sequence<Is...>>
{
private:
std::array<double, N> vals;
template <size_t >
using double_ = double;
public:
Vector(double_<Is>... vals)
{
...
}
};
例如,我们尝试下一步使用它:
Vector<3> a(1.0, 2.0, 3.0);
类型演绎如何在这里起作用?
P.S。
据我所知,当编译器看到该行时,首先,它会尝试推断出专门化的类型。它将N
推导为3,将Is
推导为空序列,然后在无法找到合适的构造函数时失败。通用模板未定义,因此编译器也必须在此处失败。但接下来会发生什么?
答案 0 :(得分:1)
此部分声明(未定义)模板类Vector的默认特化。第二个模板参数默认为索引序列0 ... N-1
template <size_t N, class = std::make_index_sequence<N>>
class Vector;
默认参数很重要,因为它用于呈现简单的界面并隐藏下一个专业化的复杂性......
此专业化是由于上述默认声明而实例化的专业化。索引序列的目的是携带Is
的可变序列(即0 ... N
- 1)。
template <size_t N, size_t... Is>
class Vector<N, std::index_sequence<Is...>>
{
定义足够的存储空间
private:
std::array<double, N> vals;
提供一种将序列Is
从size_t转换为类型(在本例中为double)的方法
template <size_t >
using double_ = double;
public:
定义要采用double_<0>
,double_<1>
... double_<N-1>
的构造函数。但double<N>
N
的任何double
都是double
的typedef。所以这一行正在做的是提供一个构造函数,每个Is
需要一个 Vector(double_<Is>... vals)
{
...
}
};
。即构建阵列所需的双倍数量。实际上它非常聪明。
\0