繁体   English   中英

为什么按值传递的数组上的 std::size 不起作用?

[英]Why does the std::size on an array passed by value do not work?

为什么std::size()不适用于按值传递的静态分配数组?

void print_elemTab(int tab[])
{
   // ...
   int size = std::size(tab); //error 
   // ...
}

void test_tab()
{
   const int    TAB_SIZE = 5;
   int          tab[TAB_SIZE] = {};
   // ...
   cout << std::size(tab) << std::endl; //print 5
   print_elemTab(tab);
   // ...
}

我正在打印尺寸,然后我在print_elemTab()中传递tab ,我再次使用std::size()

没有得到匹配的 function错误,所以我想知道为什么std::size()第一次在test_tab()而不是在print_elemTab()

我必须通过引用传递它吗? 那么,除了任意长度的数组,我该怎么做呢?

还是因为我不知道的事情,我必须以另一种方式做到这一点?

我必须通过引用传递它吗? 那么,除了任何长度的数组之外,我该怎么做呢?

的,通过引用传递它是一种选择。

template<std::size_t n>
void print_elemTab(int (&tab)[N]) // const int (&tab)[N], if the elements won't be modified
{
    std::cout << N << "\n"; // where you can directly get the size `N`
}

或者像简单的模板化 function 如下

template<typename T>
void  print_elemTab(T& tab)// const T& tab, if the elements won't be modified
{
   const auto size = std::size(tab);
   std::cout << size << "\n";
}

另一种选择是将数组推断为其实际类型。 在您的情况下, tab的类型为int[5] 如果您通过模板 function 完美转发,编译器可以推断其实际类型(而不是衰减为指针)。

#include <iostream>
#include <array>

template<typename T>
void  print_elemTab(T&& tab)
{
   const auto size = std::size(tab);  // now you can do std::size() on the int[size]
   std::cout << size << "\n";
}

表达式中使用的数组指示符被隐式转换(很少有例外,例如在sizeof运算符中使用它们)为指向它们的第一个元素的指针。

所以在这个电话中

print_elemTab(tab);

参数表达式的类型为int *

另一方面,具有数组类型的function参数被编译器调整为指向数组元素类型的指针。

例如,这些 function 声明

void     print_elemTab(int tab[]);
void     print_elemTab(int tab[5]);
void     print_elemTab(int tab[100]);

声明相同的一个 function 并且等效于以下声明

void     print_elemTab(int *tab);

你甚至不能在你的程序中包含所有这些声明,尽管编译器会发出一条消息,指出存在冗余声明。

因此,在 function 中,您正在处理int *类型的指针。 并且sizeof( int * )通常等于48 ,具体取决于所使用的系统。

如果您有这样的声明,您应该更改它,指定第二个参数,该参数将保留传递数组中的元素数量,例如

void     print_elemTab(int *tab, size_t n );

function 可以这样称呼

print_elemTab(tab, std::size( tab ) );

另一种方法是通过引用传递数组。 在这种情况下,您应该声明一个模板 function 例如

template <size_t N>
void     print_elemTab( int ( &tab )[N] );

在 function 中,您可以直接使用模板参数N作为数组中的元素数。 或者您可以将相同的标准 C++ function std::size应用于数组。

或者 function 可以使用第二个模板类型参数进行更一般的声明,例如

template <typename T, size_t N>
void     print_elemTab( T ( &tab )[N] );

另一种方法是声明 function 之类的

template <typename Container>
void     print_elemTab( Container &container );

在这种情况下,您也可以将标准 function std::size应用于参数容器。

是的,您必须通过引用传递它,因为它在传递给您的 function 时已衰减为指针。 并使 function 接受任何尺寸,我建议使用 function 模板,如下所示

#include <iostream>

template<size_t n>
void print_elemTab(int (&tab)[n])
{
    int size = std::size(tab);
    std::cout << size << "\n";// or just  std::cout << n; and ignore the previous line 
}
    
void test_tab() {
    const int TAB_SIZE = 5;
    int tab[TAB_SIZE] = {};
    std::cout << std::size(tab) << std::endl; //print 5
    print_elemTab(tab);
    
}
    
int main(){
    test_tab();
}

 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM