给定某个函数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链接,其中包含已完成的繁重工作: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 };