0

我认为不需要分配一个缓冲区来保存 string_views 的跨度。所以可能是中间人std::vector<std::string_view>?有什么好的整体模式可以将其压缩到 1 行吗?如有必要,哪种助手/实用程序最好?

std::vector<std::string> lineStorage;

std::span<std::string_view> lines = /*lineStorage */;
std::span<std::string_view, 3> linesFixed = /* lineStorage */;
4

1 回答 1

0

跨度是对该特定对象的连续缓冲区的视图,而不是协方差的抽象。

我只是传递一段字符串。吻。

假设我最终有理由变得超级花哨并且需要一个稳定的 API,那么 foo 的跨度很差。您需要按需提供多个 foo 跨度。如果跨度足够大,开销就会变得很便宜,这允许调用者不会一次分配所有数据。

template<class T>
using ask_for=function_view<void(T)>;
template<class T>
using provide=ask_for<ask_for<T>>;

然后我们采取:

void do_stuff(provide<std::span<std::string_view>> src){
  src([](std::span<std::string_view>> strings){
    // code consuming strings
  });
}

在提供者方面,我们可以制作一个字符串视图的固定缓冲区,包装字符串的 std 向量片段,并反复将固定缓冲区(带有新字符串)传递给回调。

void provide_strings(std::span<std::string> strings){
  std::size_t count = 0;
  do_stuff([&](ask_for<std::span<std::string_view>> sink){
    std::array<std::string_view, 1024> views;
    while(count<strings.size()){
      for(std::size_t i = count; i <std::min(count+1024, strings.size());++i){
        views[i-count]=strings; // I think this isn't legal, but you get the idea
      }
      sink( {views.data(), std::min(strings.size()-count, 1024ull)});
      count += 1024;
    }
  });
}

好吧有点伪代码。但我希望你能明白。

于 2021-11-07T03:31:07.960 回答