diff --git a/5-UsefulConceptsAndSTL/3-Containers.ipynb b/5-UsefulConceptsAndSTL/3-Containers.ipynb
index 2bdd15cd252fadfa1ff7337ce0d82107c51cde5f..426ca33cb41217a27ceb14da5ded59d7a051a3fc 100644
--- a/5-UsefulConceptsAndSTL/3-Containers.ipynb
+++ b/5-UsefulConceptsAndSTL/3-Containers.ipynb
@@ -387,34 +387,17 @@
     "#include <iostream>\n",
     "#include <string>\n",
     "\n",
-    "// Utility to print the content of a non-associative container.\n",
-    "// Don't bother with it now: it uses up iterators we'll see a bit below.\n",
-    "template\n",
-    "<\n",
-    "    class VectorT\n",
-    ">\n",
-    "void PrintVector(const VectorT& vector,\n",
-    "                 std::string separator = \", \", std::string opener = \"[\", std::string closer = \"]\\n\")\n",
+    "// Helper function to avoid typing endlessly the same lines...\n",
+    "template<class VectorT>\n",
+    "void PrintVector(const VectorT& vector)\n",
     "{\n",
     "    auto size = vector.size();\n",
-    "    std::cout << \"Size = \" << size << \"  Capacity = \" << vector.capacity() << \"  Content = \";\n",
-    "    std::cout << opener;\n",
-    "\n",
-    "    auto it = vector.cbegin();\n",
-    "    auto end = vector.cend();\n",
+    "    std::cout << \"Size = \" << size << \"  Capacity = \" << vector.capacity() << \"  Content = [ \";\n",
     "    \n",
-    "    static_cast<void>(end); // to avoid compilation warning in release mode\n",
-    "\n",
-    "    for (decltype(size) i = 0u; i + 1u < size; ++it, ++i)\n",
-    "    {\n",
-    "        assert(it != end);\n",
-    "        std::cout << *it << separator;\n",
-    "    }\n",
+    "    for (auto item : vector)\n",
+    "        std::cout << item << ' ';\n",
     "\n",
-    "    if (size > 0u)\n",
-    "        std::cout << *it;\n",
-    "\n",
-    "    std::cout << closer;\n",
+    "    std::cout << ']' << std::endl;\n",
     "}"
    ]
   },
@@ -433,6 +416,11 @@
     "    foo.resize(8, 10); // Second optional argument gives the values to add.\n",
     "    PrintVector(foo);\n",
     "    \n",
+    "    foo.resize(12); // If not specified, a default value is used - here 0 for a POD\n",
+    "                    // The default value is the same as the one that would be used when constructing\n",
+    "                    // an element with empty braces - here `std::size_t myvariable {}`;\n",
+    "    PrintVector(foo);\n",
+    "    \n",
     "    foo.resize(3, 15);\n",
     "    PrintVector(foo);\n",
     "}"
@@ -500,8 +488,7 @@
     "    five_pi_digits.push_back(1);\n",
     "    five_pi_digits.push_back(5);\n",
     "    \n",
-    "    for (auto item : five_pi_digits)\n",
-    "        std::cout << \"Digit = \" << item << std::endl; // Not what we intended!\n",
+    "    PrintVector(five_pi_digits); // not what we intended!\n",
     "}\n"
    ]
   },
@@ -611,9 +598,6 @@
    "source": [
     "It may not extremely efficient: at each call to `operator[]`, the program must figure out the element to draw without using the fact it had just fetched the element just in the previous memory location (in practice now compilers are rather smart and figure this out...)\n",
     "\n",
-    "**[Update]** An engineer was intrigued by this and did a benchmark... And there was no difference: compilers seem now clever enough to optimize this on their own!\n",
-    "\n",
-    "\n",
     "Iterators provides this (possibly) more efficient access:"
    ]
   },
@@ -641,7 +625,7 @@
    "source": [
     "It is more efficient and quite verbosy; prior to C++ 11 you had to use this nonetheless (just `auto` would simplify greatly the syntax here but it is also a C++11 addition...)\n",
     "\n",
-    "Iterators are *not* pointers, even if they behave really similarly, e.g. they may use the same `*` and `->` syntax (they might be implemented as pointers, but think of it as private inheritance in this case...)\n",
+    "Iterators are *not* pointers, even if they behave really similarly, e.g. they may use the same `*` and `->` syntax (they might be implemented as pointers, but think of it as [private inheritance](../2-ObjectProgramming/6-inheritance.ipynb#IS-IMPLEMENTED-IN-TERMS-OF-relationship-of-private-inheritance) in this case...)\n",
     "\n",
     "There are several flavors:\n",
     "* Constant iterators, used here, with which you can only read the value under the iterator.\n",
@@ -687,7 +671,7 @@
    "source": [
     "is undefined behaviour: it might work (seems to in this notebook) but is not robust. Here it \"works\" but you may see the iteration is done over the initial vector; the additional values aren't iterated over (we would end up with an infinite loop in this case).\n",
     "\n",
-    "So, the bottom line is you should really separate actions that modify the structure of a container and iteration over it.\n",
+    "So, the bottom line is you should really separate actions that modify the structure of a container and iterate over it.\n",
     "\n",
     "## Incrementing / decrementing iterators\n",
     "\n",
@@ -739,7 +723,7 @@
     "\n",
     "* `std::list`: A double-linked list: the idea is that each element knows the addresses of the element before and the element after. It might be considered if you need to add often elements at specific locations in the list: adding a new element is just changing 2 pointers and setting 2 new ones. You can't access directly an element by its index with a `std::list`.\n",
     "* `std::slist`: A single-linked list: similar as a `std::list` except only the pointer to the next element is kept.\n",
-    "* `std::deque`: For \"double ended queue\"; this container may be helpful if you need to store a really huge amount of data that might not fit within a `std::vector`. It might also be of use if you are to add often elements in front on the list: there is `push_front()` method as well as a `push_back` one. Item 18 of \\cite{Meyers2001} recommends using `std::deque` with `bool`: `std::vector<bool>` was an experiment to provide a specific implementation to spare memory that went wrong and should therefore be avoided...\n",
+    "* `std::deque`: For \"double ended queue\"; this container may be helpful if you need to store a really huge amount of data that might not fit within a `std::vector`. It might also be of use if you are to add often elements in front on the list: there is `push_front()` method as well as a `push_back` one. Item 18 of \\cite{Meyers2001} recommends using `std::deque` with `bool`: `std::vector<bool>` was an experiment to provide a specific implementation to spare memory when storing booleans that went wrong and should therefore be avoided...\n",
     "* `std::array`: You should use this one if the number of elements is known at compile time and doesn't change at all.\n",
     "* `std::string`: Yes, it is actually a container! I will not tell much more about it; just add that it is the sole container besides `std::vector` that ensures continuous storage."
    ]
@@ -811,5 +795,5 @@
   }
  },
  "nbformat": 4,
- "nbformat_minor": 2
+ "nbformat_minor": 4
 }