使用带有api的std :: string_view,期望null终止字符串

Pav*_*bev 10 c++ c++17

我有一个获取std::string_view和使用函数的方法,它以null终止的字符串作为参数.例如:

void stringFunc(std::experimental::string_view str) {
    some_c_library_func(/* Expects null terminated string */);
}
Run Code Online (Sandbox Code Playgroud)

问题是,处理这种情况的正确方法是什么?是str.to_string().c_str()唯一的选择吗?我真的想std::string_view在这个方法中使用,因为我在其中传递了不同类型的字符串.

Nic*_*las 15

我通过创建一个string_view名为的替代类来解决这个问题zstring_view.它是私有地继承string_view并包含其大部分接口.

主要区别在于zstring_view无法从a创建string_view.此外,任何string_view从末尾删除元素的API都不是界面的一部分,或者它们返回的是string_view而不是a zstring_view.

它们可以从任何NUL终止的字符串源创建:std::string依此类推.我甚至为它们创建了特殊的用户定义的文字后缀:_zsv.

这个想法是,只要你不zstring_view手动输入非NUL终止的字符串,所有的zstring_views都应该是NUL终止的.比如std::string,NUL字符不是字符串大小的一部分,但它就在那里.

我发现它对于处理C接口非常有用.


Ral*_*zky 7

你无法改变字符串std::string_view.因此,您无法添加终止'\0'字符.因此,您需要将字符串复制到其他位置以添加'\0'-terminator.如果字符串足够短,可以通过将字符串放在堆栈上来避免堆分配.如果你知道,这std::string_view是一个以null结尾的字符串的一部分,那么你可以检查,如果结束的'\0'字符是一个字符,并在这种情况下避免复制.除此之外,我没有看到更多的优化空间.

  • @ user1095108但是任何允许在C++中使用VLA的编译器都在应用非标准扩展,所以我认为VGA永远不会很好.:P (5认同)
  • 通过 alloca 几乎到处都支持它们,您可以使它们便携 (2认同)

Pau*_*ans 6

你当然不应该叫datastd::experimental::string_view:

与basic_string :: data()和字符串文字不同,data()可以返回指向非空终止的缓冲区的指针.

所以打电话to_string,c_str然后:

void stringFunc(std::experimental::string_view str) {
    some_c_library_func(str.to_string().c_str());
}
Run Code Online (Sandbox Code Playgroud)

要么:

void stringFunc(std::experimental::string_view str) {
    std::string real_str(str);
    some_c_library_func(real_str.c_str());
}
Run Code Online (Sandbox Code Playgroud)

  • @HowardLeeHarkness 从 C++11 开始,它 * 是 * 必然以 null 结尾。参见例如https://www.cplusplus.com/reference/string/string/data/ (4认同)