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);
这有效但怎么样?模板函数如何计算行和列大小?我在函数调用期间没有传递大小信息。我可以看到模板函数如何计算传入的对象的类型,但是在这种情况下我看不出我的ROWS和COLS是如何赋值的。
这个问题试图用模板来理解这个特例。问题不是询问矢量或存在什么其他数据结构。
答案 0 :(得分:4)
编译器是模式匹配以使调用工作。您在询问具体案例,但我不确定您的理解问题在哪里,所以我将逐步说明
在下面的示例中,我使用f
i
来呼叫int
。编译器推导出T = int
以使调用工作。您可能会说&#34;当我没有通过该类型信息时,它如何知道int
。&#34;但是你没有明确地在模板参数列表中:
template <typename T>
void f(T t) {
}
int main() {
int i = 1;
f(i); // deduces T = int
}
为了更进一步,编译器可以推导出两个不同向量参数的T是什么。对f
下面的调用有效,因为编译器可以将std :: vector模式与我传入的参数匹配:
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
}
令人印象深刻的是,即使有多个模板参数嵌套为原始示例,编译器也可以仍然查看参数并匹配模式:
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
和&
仍然有效,模式更复杂,但编译器仍然可以匹配它。什么时间活着!
答案 1 :(得分:3)
大小嵌入std::array
。由于大小是std::array
类型签名的一部分,因此该信息将传递给f
。请注意,std::array<int, 2>
和std::array<int, 3>
是完全不同的类型,无法隐式转换为彼此。