4 ms·
> If somebody else owns it and you're working on the whole string `const std::string&` is probably your best bet Actually string_view is more general. You can
by humanrebar 8y ago
> If somebody else owns it and you're working on the whole string `const std::string&` is probably your best bet
Actually string_view is more general. You can build one out of a string literal, a vector<char>, some memory from a memmap call, and an unbounded list of other things. If an interface uses a `const std::string&` and you don't have one, you have to, implicitly or explicitly, copy the data into a `std::string` to be able to use that interface.
- stochastic_monk 8y agoIs it just me, or does it seem like std::string_view is just an alternative in semantics to a `char *` plus a size? It doesn't null-terminate (which would require copying or mutating). Is there some extra safety checking this provides?
- how_gauche 8y agoUnder the hood it's just "std::pair<const char, std::size_t>". It's like an abstract data type or a newtype in Haskell: construction of the aliased type is restricted to the functions that are provided. You are correct, there is no safety --- you can call the constructor std::string_view(const char, size_t) and stuff anything you want in there. The main reason string_view is nice is the implicit conversions you get from the other string types. Pass in a "const char*", it finds the terminating null for you. Pass in a std::string, no problem. No boilerplate.
- humanrebar 8y agoThere are mild benefits to having one value that represents both a size and an address. So you're passing around a pair of things that go together instead of just using convention. But the real benefit is in providing it as a "vocabulary type". Once C++ code starts using string_view everywhere, you don't need to massage your char sequences this way and that [1] to pass it from the top of your application all the way down into the low-level libraries the application relies on. And you don't incur the overhead (both in lines of code and in copies) of all that massaging. [1] Maybe your request handler has to convert from char* and size to a string to call your business logic, then your string has to convert from a string to a char pointer and and int length to call saveName. saveName might actually use std::copy under the hood to put the data into a chunk of memory, so it turns the pointer and length into two pointers.
- gpderetta 8y ago- It has range semantics, so you can use it with standard algos or range for. - It encodes the invariant in a type (char * points to at least size bytes, no expectation of null termination, no ambiguous definition of an empty range) - The size always travel with the pointer so no chance that it gets separated. - syntactically simple conversion from string (or other string-like entities) to string view reduces clutter in the code. I consider lack of null termination a plus.
- alexhutcheson 8y agoThis is true as long as your implementation doesn't call any functions that take a `const string&`. If you need to call such a function, then you first have to make a copy of your string_view into a new string object before you call it.
- saagarjha 8y agoIs there a way to do this without involving the overhead of a full copy, though?
- alexhutcheson 8y agoNot that I'm aware of - a const std::string& parameter needs to be a reference to a std::string object, and there's no guarantee that a given string_view object is pointing to a std::string.