CppCon 2018: Victor Ciura “Enough string_view to Hang Ourselves”

preview_player
Показать описание


Wouldn’t it be nice if we had a standard C++ type to represent strings ? Oh, wait... we do: std::string. Wouldn’t it be nice if we could use that standard type throughout our whole application/project ? Well… we can’t ! Unless we’re writing a console app or a service. But, if we’re writing an app with GUI or interacting with modern OS APIs, chances are that we’ll need to deal with at least one other non-standard C++ string type. Depending on the platform and project, it may be CString from MFC or ATL, Platform::String from WinRT, QString from Qt, wxString from wxWidgets, etc. Oh, let’s not forget our old friend `const char*`, better yet `const wchar_t*` for the C family of APIs…
So we ended up with two string types in our codebase. OK, that’s manageable: we stick with std::string for all platform independent code and convert back-and-forth to the other XString when interacting with system APIs or GUI code. We’ll make some unnecessary copies when crossing this bridge and we’ll end up with some funny looking functions juggling two types of strings; but that’s glue code, anyway… right?
It’s a good plan... until our project grows and we accumulate lots of string utilities and algorithms. Do we restrict those algorithmic goodies to std::string ? Do we fallback on the common denominator `const char*` and lose the type/memory safety of our C++ type ? Is C++17 std::string_view the answer to all our string problems ?
We’ll try to explore our options, together: best practices, gotchas, things to avoid... all in the context of modern C++ projects.

Victor Ciura, CAPHYON
Software Developer

For over a decade, he designed and implemented several core components and libraries of Advanced Installer.
He’s a regular guest at Computer Science Department of his Alma Mater, University of Craiova, where he gives student lectures & workshops on “Using C++STL for Competitive Programming and Software Development”.
Currently, he spends most of his time working with his talented team on improving and extending the repackaging and virtualization technologies in Advanced Installer IDE, helping clients migrate their Win32 desktop apps to the Windows Store (MSIX).


*-----*
*-----*
Комментарии
Автор

I am surprised this talk missed the most important use of string view, besides glue code - string manipulation and querying. I am using QStringRef for years now, and all the code is for string manipulation - you can traverse, create "substrings" with zero allocation. For example get the filename from path, or the file extension, or the parent path or any combination of this - you explode the string the user passed into views, with no allocation or copying, the user can then use all this and if he decided to store any part, _then_ he will have an allocation and a copy.

And even about storing the string view is not an absolute truth. You can have value-type object that has-a string and N number of views into that string, this is correct and useful. For example, a Breadcrumbs widget can have a path and a bunch of views into that path, representing the different path components (/a/b/c/d, /a/b/c, /a/b, /a).

Lastly views are nothing new, for example image manipulation libraries like OpenCV (and others) have RIO which is Region Of Interest - it is basically non owning image (view). You create it from an image, and most if not all algorithms that work on an image type work on RIO as well.

YourCRTube
Автор

Interestingly, the equivalent of std::string_view in rust is "&str", i.e. "reference to str", which like other references is subject to the rigorous compile-time lifetime checking rust is known for, hence can normally never be dangling. The primitive "str" type represents just the string data itself (a sequence of bytes which is valid utf-8), i.e. the size is neither known at compile-time (in general) nor contained within the value itself, which is why a reference to such an object must include the size explicitly.

You can't directly create an instance of "str" btw. Rather, a &str will be typically given to you by something that manages string data storage: either the compiler in case of static data (string literals), or a String container object that manages the storage at runtime.)

Same thing for so-called "slice references", "&[T]" and "&mut [T]", basically equivalent to std::span<T const> and std::span<T> in C++20.

MatthijsvanDuin
Автор

Regarding the question to slide 44 (at ~19:10 to ~19:30), I don't think less<> makes a copy of a string. Instead it constructs another string_view from the string, which is much cheaper than a string copy.

thomasw
Автор

Slide 48 shows safe (though not performant) code assuming the string_view is valid and not dangling. Only when the caller made a mistake by passing a dangling string_view would this be of concern. In that sense the slide was misleading to the (un)safety of string_view.

araeos
Автор

I don't think the problem on slide 70 is auto. Is the "dbl" function forcing the return to T...isnt it?

brenogi
Автор

Horrible talk. An hour of bad usages and downsides of string_view and nothing about proper usage

sergeikrainov