在api中使用std :: string_view,期望null终止字符串

问题描述 投票:9回答:3

我有一个方法,它采用std::string_view并使用函数,它接受以null结尾的字符串作为参数。例如:

void stringFunc(std::experimental::string_view str) {
    some_c_library_func(/* Expects null terminated string */);
}

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

c++ c++17
3个回答
6
投票

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


13
投票

我通过创建一个名为string_view的替代zstring_view类来解决这个问题。它是私人继承自string_view并包含其大部分界面。

主要的区别是zstring_view不能用string_view创造。此外,任何从末尾删除元素的string_view API都不是界面的一部分,或者它们返回string_view而不是zstring_view

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

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

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


5
投票

你当然不应该在data上打电话给std::experimental::string_view

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

因此,请致电to_stringc_str

void stringFunc(std::experimental::string_view str) {
    some_c_library_func(str.to_string().c_str());
}

要么:

void stringFunc(std::experimental::string_view str) {
    std::string real_str(str);
    some_c_library_func(real_str.c_str());
}
© www.soinside.com 2019 - 2024. All rights reserved.