Commit 11806783 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

Add in appendix a notebook about std::string_view.

parent 67689ca1
%% Cell type:markdown id: tags:
# [Getting started in C++](./) - [Appendix](./0-main.ipynb)
%% Cell type:markdown id: tags:
This appendix groups some stuff just mentioned in earlier tutorials but that I have chosen not to speak longly about because the lecture is already long enough as it is and they might be a tiny bit more complex for some of them.
* [Breaking circular definition of shared pointers with weak pointers](./WeakPtr.ipynb) explains how to set up properly a circular relationship shared/weak pointers (unfortunately the way to set it up properly is often coyly mentioned but not explained); this is a follow-up of the notebook about [smart pointers](../5-UsefulConceptsAndSTL/6-SmartPointers.ipynb).
* [CRTP](./Crtp.ipynb) is one of my favourite idiom to provide a same functionality to utterly different classes; it was teased in the [notebook](../4-Templates/5-MoreAdvanced.ipynb) about advanced features with templates.
* [Homemade exceptions](./HomemadeException.ipynb) just provides the instantiation of the class I personally use when I want to raise an exception; it's a direct follow-up of the section that [mentioned it](../5-UsefulConceptsAndSTL/1-ErrorHandling.ipynb#The-exception-class-I-use).
* [Switch](./Switch.ipynb) is the less important one: it just explains `switch` statement and the syntax caveats you might encounter with them. It was mentioned in the [early notebook](../1-ProceduralProgramming/2-Conditions-and-loops.ipynb#switch-statement) about conditions.
* [StringView](./StringView.ipynb) explains briefly the whereabouts of `std::string_view` which was introduced in C++ 17 - and which will be expanded to other types in C++ 20.
%% Cell type:markdown id: tags:
© _CNRS 2016_ - _Inria 2018-2021_
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
......
%% Cell type:markdown id:451d5c67-1c82-4f19-9fd4-b7dd49bac7fb tags:
# [Getting started in C++](./) - [Stringview](./StringView.ipynb)
%% Cell type:markdown id:bd83674b-5f88-4d28-b959-ba315588fa67 tags:
C++ 17 introduced `std::string_view`, which basically introduces a sort of viewer over a string (not especially a `std::string`: it works basically as long as it's a chain of contiguous characters, where what is a *character* is defined as first template argument).
Let's roll an example to illustrate how it works:
%% Cell type:code id:d6cc7d26-80ba-4c0a-a276-56f9d850bbbe tags:
``` C++17
#include <string>
#include <string_view>
#include <iostream>
void print(std::string_view content)
{
std::cout << "Content is '" << content << "'" << std::endl;
}
std::string hello("Hello world from std::string!");
print(hello);
print("Hello world!");
```
%% Cell type:markdown id:e565e634-7abb-403a-af47-b46e7e9936e5 tags:
Prior to C++ 17, the usual way was to use `const std::string&` as parameter (passing a `std::string` directly would incur copies):
%% Cell type:code id:f1562c99-1b25-4314-9903-1932571fe86d tags:
``` C++17
#include <string>
#include <iostream>
void print_with_const_ref(const std::string& content)
{
std::cout << "Content is '" << content << "'" << std::endl;
}
std::string hello("Hello world from std::string!");
print_with_const_ref(hello);
print_with_const_ref("Hello world!");
```
%% Cell type:markdown id:4df1c364-df85-4a4d-a0d3-43218189354d tags:
So what did we gain exactly in the bargain?
If you remember the discussion about *l-values* and *r-values* in the [notebook about move semantics](../5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb), the construct used prior to C++ 17 doesn't necessarily make much sense: in our second call the argument `Hello world!` is clearly a r-value whereas a l-value would be expected given the prototype!
%% Cell type:markdown id:414b36fb-0179-4a0f-a963-2c931c93e12a tags:
Let's write the same *without* the `const` to convince ourselves:
%% Cell type:code id:b7471040-bffb-4a48-8ea0-2ad1fddbf442 tags:
``` C++17
#include <string>
#include <iostream>
void print_with_ref(std::string& content)
{
std::cout << "Content is '" << content << "'" << std::endl;
}
print_with_ref("Hello world!"); // COMPILATION ERROR!
```
%% Cell type:markdown id:f9dc26d5-1b95-4c75-8ca8-901e6962215e tags:
This time it doesn't work at all...
So when we provide a r-value argument to a `const std::string&` parameter, the compiler does some magic to interpret it. This magic is not without cost: a `std::string` is allocated on the fly to store the content of the r-value.
That is what `std::string_view` strives to correct: when it is used there are no such allocation involved.
So whenever possible, using `std::string_view` instead of `const std::string&` is advised - provided of course your project is firmly grounded in C++ 17 or later.
That doesn't mean there are no costs involved: when you are using `std::string_view`, you are essentially taking the responsability to ensure the memory area still exists (very similarly to the kind of contract you pass when you define a reference). [CppReference](https://en.cppreference.com/w/cpp/string/basic_string_view) illustrates this on a very basic case:
%% Cell type:code id:157f9843-02d4-4c7b-b062-f4403f911cd8 tags:
``` C++17
// Beware: the code in this cell seems to disturb Xeus-cling ability to write to std::cout...
// A ticket has been emitted: https://github.com/jupyter-xeus/xeus-cling/issues/405
#include <iostream>
#include <string>
#include <string_view>
std::string_view bad(std::string("a temporary string")); // "bad" holds a dangling pointer
// Any use of bad here will result in undefined behaviour as the `std::string` was destroyed in
// previous line when it went out of scope!
```
%% Cell type:markdown id:d8be6dd3-6ecf-4861-a556-35fe159e3445 tags:
C++ 20 will expand on this possibility for other contiguous containers with [`std::span`](https://en.cppreference.com/w/cpp/container/span).
%% Cell type:markdown id:d46d567d-50e9-4fef-a689-deaaff8d059a tags:
© _CNRS 2016_ - _Inria 2018-2021_
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment