代码之家  ›  专栏  ›  技术社区  ›  Joel Bodenmann Bob Bryan

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

  •  3
  • Joel Bodenmann Bob Bryan  · 技术社区  · 5 年前

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

    以下是coliru与已完成的grunt工作的链接: https://coliru.stacked-crooked.com/a/cb8fb8ebbc962d45

    0 回复  |  直到 5 年前
        1
  •  9
  •   catnip    5 年前

    如果您仔细考虑,要执行您要求的操作,编译器需要找到存储3的地方 std::string_view std::span 实际上不会为它引用的元素分配任何存储。


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

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