提问人:digito_evo 提问时间:5/2/2023 更新时间:5/2/2023 访问量:220
std::span::subspan()的两个重载有什么区别
What is the difference between the two overloads of std::span::subspan()
问:
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
不带参数的重载的真正目的是什么?它是为了更好的编译时评估吗?有什么优势?
答:
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>
n
std::span<T>::subspan<Offset>()
n - Offset
评论
argc
0
argc
0
0
std::errc
值。argc == 0
std::error_condition