从C字符串数组创建string_views的范围

问题描述

给定一个函数void func(std::span<std::string_view>),如何以最有效的方式为该函数提供原始的C字符串数组const char**

据我了解,由于std::string_view可以由C字符串构造,std::span可以由指针+大小构造,因此应该没有任何复制。但是,我似乎无法弄清楚正确的语法。

下面是一些最小的代码,它们通过遍历字符串数组中的每个字符串来创建std::vector<std::string_view>时有效:

#include <iostream>
#include <string>
#include <span>
#include <vector>

static void func(std::span<std::string_view> strings)
{
    // Just print the strings...
    std::cout << "strings:\n";
    for (const auto& str : strings)
        std::cout << str << "\n";
    std::cout << std::endl;
}

int main()
{
    // Raw C string array
    const char* raw_strings[3] = {
        "This is a string","This is also a string","And then another string"
    };
    
#if 1
    // This works
    std::vector<std::string_view> s;
    for (std::size_t i = 0; i < 3; i++)
        s.push_back( std::string_view{ raw_strings[i] } ); 
#else
    // This does not work
    std::span<std::string_view> s{ raw_strings,(std::size_t)3 };
#endif
        
    func(s);
}

下面是完成工作后的链接https://coliru.stacked-crooked.com/a/cb8fb8ebbc962d45

解决方法

如果考虑一下,要执行的操作是要求编译器需要找到一个存储3个std::string_view的位置,并且没有这样的位置,因为std::span实际上并未为它引用的元素。

因此,AFAICS,没有直接的方法可以做到这一点。


编辑:我认为这是最便宜的方法,因为它不涉及免费商店的分配。但是请注意,在使用跨度时,数组不会超出范围:

std::array <std::string_view,sizeof (raw_strings) / sizeof (raw_strings [0])> sa;
std::copy (std::begin (raw_strings),std::end (raw_strings),std::begin (sa));
std::span <std::string_view> s { sa };

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...