微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我只是在和 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::arraystd::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 举报,一经查实,本站将立刻删除。