当未明确说明大小信息时,模板功能如何知道尺寸


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>是完全不同的类型,无法隐式转换。

最新更新