std::span::subspan()的两个重载有什么区别

What is the difference between the two overloads of std::span::subspan()

提问人:digito_evo 提问时间:5/2/2023 更新时间:5/2/2023 访问量:220

问:

std::span<T,Extent>::subspan似乎有两个重载。

这里(直播):

#include <array>
#include <span>
#include <fmt/core.h>


void show_sizes( const std::span<const char* const> command_line_arguments )
{
    fmt::print( "{}\n", command_line_arguments.size( ) );

    const auto command_line_options { command_line_arguments.subspan( 1 ) }; // this
    const auto command_line_options { command_line_arguments.subspan<1>( ) }; // or this?

    fmt::print( "{}\n", command_line_options.size( ) );
}

int main( int argc, char* argv[] )
{
    const std::span<const char* const> command_line_arguments { argv, static_cast<std::size_t>( argc ) };
    show_sizes( command_line_arguments );
}

哪一个更适合上述情况(因为我们已经知道不能小于 1,所以 UB 可能没有机会)?argc

不带参数的重载的真正目的是什么?它是为了更好的编译时评估吗?有什么优势?

C++ C++20 标准跨度

评论

0赞 user17732522 5/2/2023
"因为我们已经知道 argc 不能小于 1“:这是不正确的。 通常允许按照 C 和 C++ 标准以及 POSIX,尽管某些操作系统(包括最近的 Linux 版本)确保它不会发生。因此,无论哪种方式,UB都有潜力。argc0
0赞 digito_evo 5/3/2023
@user17732522 那我该如何预防UB呢?
1赞 user17732522 5/3/2023
通过在获取子跨度之前添加一个检查,该检查不是或原始跨度没有大小。argc00
0赞 digito_evo 5/3/2023
@user17732522 对。我想我更喜欢检查原始跨度的大小。
0赞 digito_evo 5/3/2023
@user17732522 您认为什么适合作为此类失败的错误代码(即程序何时返回退出代码 1)?我有一个函数可以处理与启动相关的错误并返回一个,但我找不到这个特定错误的有意义的 std::errc 值。argc == 0std::error_condition

答:

2赞 Artyer 5/2/2023 #1

第一个重载适用于固定大小的跨度,如果其范围可以静态已知。例如:

// A `std::span<T, 3>` of the last 3 elements
std::span<T, 5>{...}.subspan<2>();

// A `std::span<T, 5>` of the first 5 elements after skipping the first
std::span<T>{...}.subspan<1, 5>();

对于 vs,在行为上没有区别,因为大小仍然未知。std::span<T>{...}.subspan<N>()std::span<T>{}.subspan(N)

评论

0赞 digito_evo 5/3/2023
那么应该选择哪一个呢?
1赞 Artyer 5/3/2023
@digito_evo 纯属见仁见智。如果您不使用静态范围跨度,我个人会选择.subspan( 1 )
0赞 Yakk - Adam Nevraumont 5/3/2023
你的最后一句话没有意义?在编译时,模板的参数是已知的,所以我不确定你的意思。
0赞 Artyer 5/3/2023
@Yakk-AdamNevraumont 如果 a 的大小为 (不在类型中,因为它具有动态范围),则将具有 大小 ,仍然未知,从而导致另一个具有动态范围的跨度std::span<T>nstd::span<T>::subspan<Offset>()n - Offset