【问题标题】:C++ templates with multiple typenames具有多个类型名的 C++ 模板
【发布时间】:2012-11-06 20:34:19
【问题描述】:

我正在学习一种用于查找数组中元素数量的技术(这样我就可以开始编写排序算法,而无需将数组的长度作为参数传递给数组),但是在教程,这一行显示为模板声明:

template <typename T, size_t N>

老实说,我不知道你可以在一个模板声明中声明多个类型名,但“size_t N”还有什么作用?这也是模板声明中的变量声明吗?

【问题讨论】:

  • 没有 size_t 意味着您正在使用 size_t 类型的整数值创建模板,如果您使用的是编译时数组(通常用于小 N),这可以帮助您。你要明白typename T的意思是T是模板中泛型类型的占位符。
  • size_t 是一种无符号类型,用于包含某种大小,例如以字节数或字符数表示的缓冲区大小。
  • 请注意有std::arraystd::extent。这些也可以帮助您处理数组中的元素数量。
  • @DyP,有趣,我很久以前才看到std::extent,忘记了。
  • @chris 虽然我不明白他们为什么没有提供 constexpr 函数来推断长度。

标签: c++ arrays function templates


【解决方案1】:

size_t 是类似于unsigned int 的类型。将它放在模板参数中仅意味着您传递了size_t,而不是类型。 N 可能代表一个数组的大小,它是一个无符号值。例如:

template<typename T, size_t N>
void zeroArray(T (&arr)[N]) {    //arr is a reference to an array 
    std::fill(arr, arr + N, 0);  //of N elements of type T
}

int main() {
    int arr[3];
    zeroArray<int, 3>(arr);
}

在示例中,我可以说:

zeroArray(arr);

因为两个模板参数都是推导出来的。

【讨论】:

  • 注意:如果使用 C++11,std::beginstd::end 适用于数组,因此您可以使用它们来代替 arrarr + N。您也可以为 C++03 制作自己的。
  • 我在我的笔记本电脑上使用 fedora 作为主要操作系统,老实说,我完全不知道我使用的是什么版本的 C++(我会在发布后谷歌如何检查它)但是我确实有一个问题。我不断安装所有可用的更新,是否为大多数 linux 系统更新了 c++ 库?
  • @kjh,我不确定;我不使用Linux。不过,您可以做的一件事来检查您的版本是打印__cplusplus 的值。但是,我记得 GCC 有一段时间没有更新它。我知道 GCC 4.7.2 设置正确。
【解决方案2】:

“size_t N”是做什么的?这也是模板声明中的变量声明吗?

是的,基本上。

模板参数可以是整数类型的类型或值。它们也可以是其他一些东西(请参阅[C++11: 14.3.2/1]),我不会称它们为“变量”本身,但是...

无论如何,值也可以像类型一样推导出来,所以:

template <typename T, size_t N>
size_t array_size(const T (&)[N])
{
    return N;
}

int main()
{
   int  x[5];
   char y[10];
   std::string z[20];

   std::cout << array_size(x) << ',' << array_size(y) << ',' << array_size(z) << '\n';
}

输出:5,10,20

完全有效。

【讨论】:

  • 我不会称它为变量(prvalue)。还有更多类型可以使用(我想你知道,仅供参考)。
  • @DyP:谁称它为变量?是的,它们列在[C++11: 14.3.2/1] 中。仅供参考。
  • OP,你似乎同意(“这是一个变量声明”)。
  • @DyP:哦,哎呀。抱歉没有看报价单。好吧好吧……是的。 :) 现在好点了吗?
猜你喜欢
  • 2013-11-24
  • 2020-10-27
  • 1970-01-01
  • 2019-01-06
  • 2017-05-31
  • 2023-01-25
  • 2021-12-08
  • 2021-12-28
  • 1970-01-01
相关资源
最近更新 更多