在编译时获取未确定大小的数组的长度

我只是在和 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)>,即使没有优化,它也应该编译为空。


以上是在编译时获取未确定大小的数组的长度的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>