如何解决在编译时获取未确定大小的数组的长度
我只是在和 Compiler Explorer 混为一谈……我问自己为什么 C++ 中没有 lenth() 函数来确定编译时数组的大小,因为在我看来它应该很容易写。但显然这并不容易。我的想法是这样的:
#include <iostream>
using namespace std;
void print_all(const int num[],const size_t n)
{
for (size_t i = 0; i < n; ++i)
cout << num[i] << endl;
}
template <class T,size_t N>
constexpr size_t length(T (&arr)[N])
{
return N;
}
int main()
{
constexpr int a[] { 1,2,3,4 };
print_all(a,length(a));
}
但是,根据带有 clang 11.0.1,x86-64 的 Godbolt.org,这将被编译为以下内容:
main: # @main
...
call unsigned long length<int const,4ul>(int const (&) [4ul])
mov rdi,qword ptr [rbp - 24] # 8-byte Reload
mov rsi,rax
call print_all(int const*,unsigned long)
xor eax,eax
add rsp,32
pop rbp
ret
unsigned long length<int const,4ul>(int const (&) [4ul]): # @unsigned long length<int const,4ul>(int const (&) [4ul])
push rbp
mov rbp,rsp
mov qword ptr [rbp - 8],rdi
mov eax,4
pop rbp
ret
所以它不是内联的。
PS:我对这个不感兴趣,因为我实际上想使用这样的功能。我知道在几乎所有情况下 std::array
或 std::span
都会是更好的解决方案,并且 print_all
中的原始循环是可疑的等等。我问这个是因为我想提高我对C++ 并且因为不确定大小的数组“在野外”出现。
我也知道我可以使用 sizeof(a)/sizeof(a[0])
,但我认为应该有一种方法可以使用模板和 constexpr
来完成这样的事情,因为这在某种程度上就是它们的用途(创造可以在编译时支付)。
解决方法
std::size(a)
的作用与您的 length(a)
完全相同,因此这不是一个坏主意。正如其他人所说,如果您启用优化,函数调用将被删除。
您也可以执行 std::extent_v<decltype(a)>
,即使没有优化,它也应该编译为空。
正如评论中已经指出的那样,启用优化确实会删除调用。或者,您可以使用 C++ 属性;使用 GCC 和 clang 插入 [[gnu::always_inline]]
将始终省略调用:
template <class T,size_t N>
[[gnu::always_inline]] constexpr size_t length(T (&arr)[N])
{
return N;
}
其他编译器有 different ways 强制这种行为。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。