在我的文件中,我创建了函数长度,该函数长度必须返回自动类型数组的长度,而不是每次返回1时都要正确回答。
Use one of the following commands:
clickhouse local [args]
clickhouse client [args]
clickhouse benchmark [args]
clickhouse server [args]
clickhouse extract-from-config [args]
clickhouse compressor [args]
clickhouse format [args]
clickhouse copier [args]
clickhouse obfuscator [args]
答案 0 :(得分:2)
您正在使用C样式数组,并且无法复制此类型。
如果我们假设您的编译器的版本支持
auto
个参数,就好像它有一个template
参数
在这里可以推导为int *
,因为相反
复制后,C样式的数组会衰减为int *
。
在这种情况下,sizeof(arr)
是sizeof(int *)
,可能是
在32位系统上为4,在64位系统上为8。
sizeof(*arr)
是sizeof(int)
,在大多数系统上可能是4。
因此,sizeof(arr)/sizeof(arr[0])
中的length()
总是给1或2。
如果要使用这样的函数返回元素数
数组,您可以使用std::array()
类型
评论建议。
另一种方法是提供模板功能 知道数组的常量(在编译时已知)大小。
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
template<typename T,
int N>
int
length([[maybe_unused]] const T(&arr)[N])
{
return N;
}
int
main()
{
int arr[] = {1,2,3,4,5,0};
std::cout << length(arr) << '\n';
return 0;
}
答案 1 :(得分:1)
是的,您已经成为经典阵列衰减问题的受害者。
当具有接收数组的函数时,C会将其作为指针传递,因为“数组”不是可传递的数据类型。您得到1是因为sizeof(arr) == sizeof(size_t) == sizeof(*arr) == sizeof(int)
,所以sizeof(arr) / sizeof(*arr) == 1
。
不幸的是,无法在子函数中找到C样式数组的长度。但是,您可以执行一些操作:
您也可以将长度传递给函数。不幸的是,如果您要一个长度函数,这是很失败的。但是,它用于许多需要支持空字节的C样式应用程序。
您可以使用C ++样式std::array
,该样式允许您使用size()
查找数组的大小。这使您无需使用C恶作剧就可以创建数组。您还可以使用std::vector
,它是可变大小而不是固定大小。
答案 2 :(得分:1)
将数组直接传递给函数是不可能的(按值表示),尝试这样做是将指针传递给它的第一个元素。其他答案已经解释了这一点。
您可以做的是传递参考:
int length(const auto &arr)
{
return sizeof(arr) / sizeof(*arr);
}
这适用于数组,但对于指针,标准容器等却给出错误的结果。
要使其更加防弹,可以对其进行重写以使其仅接受对数组的引用:
template <typename T, std::size_t N>
std::size_t length(const T (&)[N])
{
return N;
}
但是我们已经有一个标准函数可以执行此操作,它称为std::size
。而且使用容器也很麻烦。
答案 3 :(得分:1)
您的代码完全可以编译是因为您的编译器(gcc?)支持非标准扩展。
最好使用标准容器(例如,Output
如果大小在运行时确定,或者std::vector<int>
如果大小在编译时确定)。
但是,对于使用原始数组并给出其大小的函数,您可以简单地传递引用;
std::array<int, 6>
或
int length(const auto &arg) {return sizeof(arr)/sizeof(*arr);}
根据您的需要,也可以将功能设置为 template<int N> int length(const int (&arr)[N])
{
return N;
}
和constexpr
。
在C ++ 17和更高版本中,只需使用辅助函数noexcept
(在各种标准标头中提供,例如std::size()
,并可以使用原始数组和标准容器)>
<iterator>