【问题标题】:How can I get the length of an array that was passed to a function?如何获取传递给函数的数组的长度?
【发布时间】:2020-08-03 22:42:42
【问题描述】:

给定以下函数:

template<class T>
void foo(T* ar)
{
    std::cout << sizeof(ar) / sizeof(ar[0]) << std::endl;
    for (int i = 0; i < 6; i++)
        std::cout << ar[i] << " ";
}

以下数组:

int ar[] = { 5, 1, 6, 8, 9, 3 };
foo(ar);

我希望程序先打印“6”,然后再打印数组的内容。但由于某种原因,sizeof(ar) / sizeof(ar[0]) 的计算结果为 1(因为 sizeof(ar)sizeof(ar[0]) 的计算结果都为 '4'),但打印工作正常(意味着传递的数组确实包含所有 6 个元素)。

这只发生在传递给函数的数组上(我尝试在 main() 中评估长度,其中声明了数组并且工作正常)。如何获取函数内数组的长度?

【问题讨论】:

  • 您无法通过指针获取长度。这就是为什么使用std::vector 是传递数组的首选方式
  • @UnholySheep,所以如果我必须使用数组,唯一的方法就是将长度也传递给函数?
  • 数组ar在传递给函数时衰减为指针,所以foo中的ar只是一个指针
  • 你应该传递一个array_view,或者通过引用传递数组,或者显式传递大小。永远不要使用sizeof(ar) / sizeof(ar[0]) 之类的东西来计算数组的大小,而是使用::std::size

标签: c++ arrays pass-by-reference sizeof function-definition


【解决方案1】:

只需将参数声明为具有引用类型即可。

例如

template<class T>
void foo( const T &ar )
{
    size_t n = sizeof(ar) / sizeof(ar[0]);
    std::cout << n << std::endl;
    for (int i = 0; i < n; i++)
        std::cout << ar[i] << " ";
}

或者你可以使用下面的声明

template<class T, size_t N>
void foo( const T ( &ar )[N] )
{
    std::cout << N << std::endl;
    for (int i = 0; i < N; i++)
        std::cout << ar[i] << " ";
}

否则函数处理指针。在这种情况下,您需要指定第二个参数来表示数组的长度,例如

template<class T>
void foo( const T* ar, size_t n )
{
    std::cout << n << std::endl;
    for (int i = 0; i < n; i++)
        std::cout << ar[i] << " ";
}

由于传递的数组在函数中没有被改变,所以相应的参数应该有限定符const

注意在C++ 17标准中引入了标准函数std::size在头文件&lt;iterator&gt;中声明,可以使用 而不是表达式sizeof(ar) / sizeof(ar[0])

所以你可以在第一个显示的函数中编写示例

size_t n = std::size(ar)`;

【讨论】:

  • 我想我会选择第一个,void foo( const T &amp;ar ),但在这种情况下,类型 T 变为 array。有没有办法获取该数组元素的类型?
  • @Ach113 您可以包含标题 并使用 typename std::remove_extent_t<:remove_reference_t ar>> x;
  • @Ach113 您可以通过使用别名声明来缩短这条长记录。例如使用 Type = typename std::remove_extent_t<:remove_reference_t ar>>;输入 x = 10;
  • 问题是,我想创建一个 SomeObject&lt;T&gt; 类型的对象。我需要将int 之类的数据类型传递给它。但是如果 T 变成一个数组,在这种情况下我该怎么办?
  • @Ach113 你可以像 template void foo( const T &ar, typename std::remove_extent_t x ); 这样声明函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 2013-07-11
  • 2014-10-14
相关资源
最近更新 更多