将主要参数转换为没有范围的 span<std::string_view>

Convert main args to span<std::string_view> without ranges

这个问题是 通过使用范围来解决的,但我使用的是 C++17 和 std::span 的向后端口 - 所以我有跨度但没有范围。

考虑这个简单的函数:

std::span<std::string_view> cmdline_args_to_span(int argc, const char* argv[])
{
    return std::span<const char*>(argv, argc);
}

认为 span 的转换构造函数会由于 std::string_viewconst char* 构造函数而启动,但事实并非如此。也不是:

std::span<std::string_view> cmdline_args_to_span(int argc, const char* argv[])
{
    auto c_args = std::span<const char*>(argv, argc);
    return std::span<std::string_view>(c_args);
}

或者:

std::span<std::string_view> cmdline_args_to_span(int argc, const char* argv[])
{
    auto c_args = std::span<const char*>(argv, argc);
    return std::span<std::string_view>(c_args.begin(), c_args.end());
}

All of these fail 在 Clang 和 gcc 上(使用 'real' std::span 但我的反向移植版本是一样的)。

我一定是在做一些愚蠢的事情,但我看不到什么 - 有人可以帮忙吗?

Convert main args to `spanstd::string_view without ranges

This question has been answered before

您会注意到“之前已回答”解决方案根本不会创建 std::span<std::string_view>

std::span 不是一个适配器范围,其迭代器将在间接生成对象时生成对象,例如 std::views::transform is and does。你不能有一个 std::span<std::string_view> 除非你有一个 std::string_view 对象数组。这些对象不会存储在跨度内。

std::span<std::string_view> 对于命令行参数不是很方便。但是,您可以先创建一个 std::vector<std::string_view>,然后创建一个指向向量的跨度。由于命令行参数是全局的,因此静态存储不会出现重大问题的情况很少见 - 除非调用者错误地认为他们可以使用不同的参数来调用它:

std::span<std::string_view>
cmdline_args_to_span(int argc, const char* argv[])
{
    static std::vector<std::string_view> args(argv, argv + argc);
    return args;
}

but I'm using C++17 with a backport of std::span - so I have spans but not ranges.

范围可以有 pre-C++20,即使标准库没有它们。事实上,标准范围基于在 C++14 中运行的库。

就是说,如果您对使用任何 pre-existing 范围库不感兴趣,那么您自己实现转换视图会涉及相当多的样板文件。