将主参数转换为不带范围的 span<std::string_view>



这个问题以前已经通过使用范围得到了回答,但我使用的是带有std::span后台端口的C++17,所以我有范围,但没有范围。

考虑一下这个简单的函数:

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());
}

所有这些在Clang和gcc上都失败了(使用"真正的"std::span,但对我的后端口版本来说是一样的(。

我一定在做一些愚蠢的事情,但我看不出什么——有人能帮忙吗?

将主参数转换为`spanstd::string_view,不带范围

这个问题已经在之前得到了回答

您会注意到;在";解决方案根本不会创建std::span<std::string_view>

std::span不是一个适配器范围,其迭代器将在间接生成对象,例如std::views::transform是并且确实是。除非有std::string_view对象的数组,否则不能有std::span<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;
}

但我使用的是带有std::span的后端口的C++17,所以我有跨度,但没有范围。

范围可以在C++20之前使用,即使标准库没有。事实上,标准范围是基于一个在C++14中工作的库。

也就是说,如果您对使用任何预先存在的范围库都不感兴趣,那么自己实现转换视图需要相当多的样板。

相关内容

最新更新