之前已經通過使用范圍回答了這個問題,但我使用的 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會由于const char*建構式而啟動,std::string_view但事實并非如此。也不是:
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,但對于我的反向移植版本是一樣的)。
我一定是在做一些愚蠢的事情,但我看不出是什么——有人能幫忙嗎?
uj5u.com熱心網友回復:
將主要引數轉換為不帶范圍的`spanstd::string_view
這個問題之前已經回答過了
您會注意到“之前已回答”的解決方案根本不會創建一個std::span<std::string_view>。
std::span不是一個配接器范圍,其迭代器將在間接時生成物件,例如std::views::transformis 和 does。std::span<std::string_view>除非你有一個物件陣列,否則你不能擁有 a 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;
}
但我使用 C 17 和 std::span 的反向埠 - 所以我有跨度但沒有范圍。
即使標準庫沒有范圍,C 20 之前也可以有范圍。事實上,標準范圍基于在 C 14 中作業的庫。
也就是說,如果您對使用任何預先存在的范圍庫不感興趣,那么您自己實作轉換視圖會涉及相當多的樣板檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/440071.html
