在编译时获取未确定大小的数组的长度
我只是在和 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)>,即使没有优化,它也应该编译为空。