template<size_t ROWS, size_t COLS>
void f(const array<array<int, COLS>, ROWS>& arr)
{
for(size_t r=0; r<ROWS; r++)
for(size_t c=0; c<COLS; c++)
//stuff
}
array<array<int, 2>, 3> arr {{{1,2},{3,4},{5,6}}};
f(arr);
这有效,但是如何?模板功能如何弄清楚行和COL大小?在函数通话过程中,我没有传递尺寸信息。我可以看到模板函数如何找出要传递的对象的类型,但是在这种情况下,我看不到我的行和col的值。
这个问题寻求使用模板对这种特殊情况的理解。这个问题不是询问向量或其他数据结构。
编译器是模式匹配以使呼叫起作用。您正在询问特定案例,但我不确定您的问题在哪里,所以我将在步骤
中说明在下面的示例中,我用i
调用f
,即int
。编译器推论T = int
以获取工作电话。您可能会说:"当我没有传递该类型信息时,它如何知道int
。"但是,您只是在模板参数列表中没有明确说明:
template <typename T>
void f(T t) {
}
int main() {
int i = 1;
f(i); // deduces T = int
}
为了更进一步,编译器可以推断出两个不同矢量参数的t。下面对f
的调用工作是因为编译器可以将std ::向量模式与我传递的参数匹配:
template <typename T>
void f(std::vector<T> v) {
}
int main() {
std::vector<int> v1;
f(v1); // deduces T = int
std::vector<std::string> v2;
f(v2); // deduces T = std::string
}
在下一个示例中,我创建了一个只有一个参数的类,即size_t
,并且编译器仍然能够与Cls<I>
模式匹配
template <std::size_t N>
class Cls { };
template <std::size_t I>
void f(Cls<I> v) {
}
int main() {
Cls<3> c1;
f(c1); // deduces I = 3
Cls<100> c2;
f(c2); // deduces I = 100
}
std::array
版本以相同的方式工作,涉及std::array
的另一个明确的模板参数:
template <std::size_t I>
void f(std::array<int, I> v) {
}
int main() {
std::array<int, 3> a1;
f(a1); // deduces I = 3
std::array<int, 100> a2;
f(a2); // deduces I = 100
}
令人印象深刻的是,即使有多个模板参数嵌套为您的原始示例,编译器也可以 still 查看参数并匹配模式:
template<size_t ROWS, size_t COLS>
void f(std::array<std::array<int, COLS>, ROWS> arr) {
}
int main() {
std::array<std::array<int, 2>, 3> arr{};
f(arr); // deduces COLS = 2 and ROWS = 3 !!
}
在上述示例中添加const
和&
仍然有效,模式更为复杂,但编译器仍然可以匹配它。多么活的时间!
大小嵌入在std::array
中。由于大小是std::array
的类型签名的一部分,因此该信息将传递给f
。请记住,std::array<int, 2>
和std::array<int, 3>
是完全不同的类型,无法隐式转换。