Using std :: string_view with api, expects a null-terminated string

I have a method that takes std::string_view and uses a function that takes a zero-terminated string as a parameter. For instance:

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

The question is, what is the right way to deal with this situation? Is str.to_string().c_str() only option? And I really want to use std::string_view in this method, because I pass in it different types of strings.

+10
source share
3 answers

You cannot change the string via std::string_view . Therefore, you cannot add the terminating character '\0' . Therefore, you need to copy the line somewhere else to add the '\0' -terminator. You can avoid heap allocation by putting a line on the stack if it is short enough. If you know that std::string_view is part of a string with a terminating zero, then you can check if the character after the end is the character '\0' and avoids copying in this case. Other than that, I see no more room for optimization.

+7
source

I solved this problem by creating an alternative string_view class called zstring_view . It is privately inherited from string_view and contains most of its interface.

The fundamental difference is that zstring_view cannot be created from string_view . In addition, any string_view that remove elements from the end are not part of the interface or return string_view instead of zstring_view .

They can be created from any NUL-terminal string source: std::string and so on. I even created special custom letter suffixes for them: _zsv .

The idea is that until you manually place a line without zstring_view in zstring_view , all zstring_view must be NUL-terminated. Like std::string , the NUL character is not part of the size of the string, but it is.

I believe that this is very useful for interacting with the C interface.

+14
source

You certainly shouldn't call data on std::experimental::string_view :

Unlike basic_string :: data () and string literals, data () can return a pointer to a buffer that does not end with zero.

So call to_string and c_str to:

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

or

 void stringFunc(std::experimental::string_view str) { std::string real_str(str); some_c_library_func(real_str.c_str()); } 
+6
source

Source: https://habr.com/ru/post/1013428/


All Articles