From da37c5c74c2008ef08481ce14c499ee57770e0ec Mon Sep 17 00:00:00 2001
From: Marcus Mohr <marcus.mohr@lmu.de>
Date: Mon, 28 Oct 2024 15:41:19 +0100
Subject: [PATCH] Small changes to notebooks 01-04 after using them in WiSe
 2024/2025

---
 notebooks/01_Overloading.ipynb         | 477 ++++++++++++++++++++-
 notebooks/02_Pointers+References.ipynb | 367 +++++++++++++++-
 notebooks/03_ParameterPassing.ipynb    | 556 ++++++++++++++++++++++++-
 notebooks/04_Classes+Objects.ipynb     | 343 ++++++++++-----
 4 files changed, 1645 insertions(+), 98 deletions(-)

diff --git a/notebooks/01_Overloading.ipynb b/notebooks/01_Overloading.ipynb
index 7800c7e..acaa90d 100644
--- a/notebooks/01_Overloading.ipynb
+++ b/notebooks/01_Overloading.ipynb
@@ -1 +1,476 @@
-{"cells":[{"metadata":{"tags":[]},"id":"235e90d0-cc51-48c6-9df4-399338da447a","cell_type":"markdown","source":"# Overloading\n\nIn C++ functions that expect different types or numbers of parameters can still have the same name. This is called **overloading** and constitues a form of **static polymorphism**."},{"metadata":{},"id":"90ce7880-230c-4723-bbb0-09bb0ce9be7e","cell_type":"markdown","source":"### Example #1\nWe are going to implement two free-functions that return the magnitude of their argument."},{"metadata":{"trusted":true},"id":"eec83314-77dd-473c-9350-74d59ee80a28","cell_type":"code","source":"// Version for int\nint getMagnitude( int input ) {\n  return input > 0 ? input : -input;\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"id":"bdf6437f-1345-4341-89ad-2e1bfccf3f51","cell_type":"code","source":"// Version for double\ndouble getMagnitude( double input ) {\n  return input > 0.0 ? input : -input;\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"id":"b729878a-62d9-4f61-89c5-a4cdaba10d17","cell_type":"code","source":"// A driver to check that this works\n#include <iostream>\n\nint main() {\n  double dVal = -5.2;\n  std::cout << \"|\" << dVal << \"| = \" << getMagnitude( dVal )\n            << \", |2| = \" << getMagnitude( 2 ) << std::endl;\n}","execution_count":null,"outputs":[]},{"metadata":{},"id":"5b6c893e-1883-482c-8415-0ccdebfba63d","cell_type":"markdown","source":"Let's execute our program. In our notebook we can do this by invoking the main() function:"},{"metadata":{"trusted":true},"id":"7ee16102-554c-45c2-8355-dc68d10b2243","cell_type":"code","source":"main()","execution_count":null,"outputs":[]},{"metadata":{},"id":"3b86fe70-835c-4358-9c46-f1b582327fa0","cell_type":"markdown","source":"What's the last line with the 0?"},{"metadata":{},"id":"6a52697f-6c1b-4561-8626-a56a75d80f75","cell_type":"markdown","source":"### Example #2"},{"metadata":{},"id":"d418a230-01d8-4d6b-a24b-c16bb3211f27","cell_type":"markdown","source":"A simple function that echos its input to standard output"},{"metadata":{"trusted":true},"id":"4229aeb8-1ec6-4fe1-b7fd-6a2fe4573255","cell_type":"code","source":"void display( const std::string mesg ) {\n  std::cout << mesg << std::endl;\n}","execution_count":null,"outputs":[]},{"metadata":{},"id":"4f81e8dd-ee8c-4714-b9ae-a40e0099e671","cell_type":"markdown","source":"Another version of display() which differs from the former in:\n- expects a 2nd argument\n- indents the string by depth blanks"},{"metadata":{"trusted":true},"id":"c224bdfb-91a2-4519-acfb-183864ab4726","cell_type":"code","source":"void display( const std::string mesg, int depth ) {\n  std::string indent( depth, ' ' );\n  std::cout << indent << mesg << std::endl;\n}","execution_count":null,"outputs":[]},{"metadata":{},"id":"4468de2f-f108-41b2-a8c5-2d4c49d79987","cell_type":"markdown","source":"Let's use both to do some simple drawing"},{"metadata":{"trusted":true},"id":"d1acaf75-c148-4aa8-a407-d2391a64fd33","cell_type":"code","source":"int main() {\n  const int len = 15;\n  std::string stars( len, '*' );\n  display( stars );\n  for( unsigned int k = 1; k < stars.length(); k++ ) {\n    display( stars.substr( k, std::string::npos ), k );\n  }\n}\n\nmain()","execution_count":null,"outputs":[]},{"metadata":{},"id":"b518bf97-ab4e-4fbb-90cb-efb9dde87f6f","cell_type":"markdown","source":"If we do not know about some standard C++ function or object, we can ask for help:"},{"metadata":{"trusted":true},"id":"79748a7a-6695-4ac0-b1a2-b3de4610d3c6","cell_type":"code","source":"?std::string","execution_count":null,"outputs":[]},{"metadata":{},"id":"e381e911-aa5c-43bd-a3d5-2c25a7a0ab3e","cell_type":"markdown","source":"### Example #3\nWe want to implement two functions that return a zero for initialising new variables."},{"metadata":{},"id":"482d9fcc-e25f-4be2-883c-8c10e7b0ffaf","cell_type":"markdown","source":"The magic command **%%file** will write the contents of the cell to the given file"},{"metadata":{"trusted":true},"id":"a0160540-141d-49a8-a16b-0832deb45111","cell_type":"code","source":"%%file example.cpp\nint zero() {\n  return 0;\n}\n\ndouble zero() {\n  return 0.0;\n}\n\nint main() {\n  double dVal = zero();\n  int iVal = zero();\n}","execution_count":null,"outputs":[]},{"metadata":{},"id":"5e2ece20-14ea-4eab-b147-c2056abcb54d","cell_type":"markdown","source":"Now let's check whether GCC will compile it?"},{"metadata":{"trusted":true},"id":"ecd5b116-b2f7-453f-9bdf-fd4d424f5161","cell_type":"code","source":"!g++ example.cpp","execution_count":null,"outputs":[]},{"metadata":{},"id":"2c71fc09-d97c-4f25-ba9e-cd013edda551","cell_type":"markdown","source":"Wasn't aware that 'ambiguate' was a noun ;-) Let's see what clang will tell us"},{"metadata":{"trusted":true},"id":"3cb990eb-aef8-464b-ac85-644c0d7b57c2","cell_type":"code","source":"!clang++ example.cpp","execution_count":null,"outputs":[]},{"metadata":{},"id":"1e494c0f-d7a1-4412-b67b-5911f5d7d46b","cell_type":"markdown","source":"Okay, so apparently overloading does not work, for **'functions that differ only in their return type'**.\nWell, we might remember that the **signature of a function** consists of the number and type of its arguments, but not its return type.\nWe can check on that by the following:"},{"metadata":{"trusted":true},"id":"91797c03-d79d-446d-946a-1ecdd8184f44","cell_type":"code","source":"%%file signature.cpp\n\nint getMagnitude( int input ) {\n  return input > 0 ? input : -input;\n}\n\ndouble getMagnitude( double input ) {\n  return input > 0.0 ? input : -input;\n}\n\nint getMagnitude( short input ) {\n  return input > 0 ? input : -input;\n}\n\nvoid demo( double dVal, float fVal, int* iPtr ){};","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"id":"07ca2086-0fc4-41df-8061-40aa13bc7f67","cell_type":"code","source":"!g++ -c signature.cpp","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"id":"773be3ed-09bb-48bc-9af6-75a6156db75c","cell_type":"code","source":"!nm -C signature.o","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"name":"xcpp17","display_name":"C++17","language":"C++17"},"language_info":{"codemirror_mode":"text/x-c++src","file_extension":".cpp","mimetype":"text/x-c++src","name":"c++","version":"17"}},"nbformat":4,"nbformat_minor":5}
\ No newline at end of file
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "235e90d0-cc51-48c6-9df4-399338da447a",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "# Overloading\n",
+    "\n",
+    "In C++ functions that expect different types or numbers of parameters can still have the same name. This is called **overloading** and constitues a form of **static polymorphism**."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "90ce7880-230c-4723-bbb0-09bb0ce9be7e",
+   "metadata": {},
+   "source": [
+    "### Example #1\n",
+    "We are going to implement two free-functions that return the magnitude of their argument."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "eec83314-77dd-473c-9350-74d59ee80a28",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Version for int\n",
+    "int getMagnitude( int input ) {\n",
+    "  return input > 0 ? input : -input;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "bdf6437f-1345-4341-89ad-2e1bfccf3f51",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Version for double\n",
+    "double getMagnitude( double input ) {\n",
+    "  return input > 0.0 ? input : -input;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "b729878a-62d9-4f61-89c5-a4cdaba10d17",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// A driver to check that this works\n",
+    "#include <iostream>\n",
+    "\n",
+    "int main() {\n",
+    "  double dVal{ -5.2 };\n",
+    "  std::cout << \"|\" << dVal << \"| = \" << getMagnitude( dVal )\n",
+    "            << \", |2| = \" << getMagnitude( 2 ) << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5b6c893e-1883-482c-8415-0ccdebfba63d",
+   "metadata": {},
+   "source": [
+    "Let's execute our program. In our notebook we can do this by invoking the main() function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "7ee16102-554c-45c2-8355-dc68d10b2243",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "|-5.2| = 5.2, |2| = 2\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "main()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3b86fe70-835c-4358-9c46-f1b582327fa0",
+   "metadata": {},
+   "source": [
+    "What's the last line with the 0?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6a52697f-6c1b-4561-8626-a56a75d80f75",
+   "metadata": {},
+   "source": [
+    "### Example #2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d418a230-01d8-4d6b-a24b-c16bb3211f27",
+   "metadata": {},
+   "source": [
+    "A simple function that echos its input to standard output"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "4229aeb8-1ec6-4fe1-b7fd-6a2fe4573255",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void display( const std::string mesg ) {\n",
+    "  std::cout << mesg << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4f81e8dd-ee8c-4714-b9ae-a40e0099e671",
+   "metadata": {},
+   "source": [
+    "Another version of display() which differs from the former in:\n",
+    "- expects a 2nd argument\n",
+    "- indents the string by depth blanks"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "c224bdfb-91a2-4519-acfb-183864ab4726",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void display( const std::string mesg, int depth ) {\n",
+    "  std::string indent( depth, ' ' );\n",
+    "  std::cout << indent << mesg << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4468de2f-f108-41b2-a8c5-2d4c49d79987",
+   "metadata": {},
+   "source": [
+    "Let's use both to do some simple drawing"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "d1acaf75-c148-4aa8-a407-d2391a64fd33",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "***************\n",
+      " **************\n",
+      "  *************\n",
+      "   ************\n",
+      "    ***********\n",
+      "     **********\n",
+      "      *********\n",
+      "       ********\n",
+      "        *******\n",
+      "         ******\n",
+      "          *****\n",
+      "           ****\n",
+      "            ***\n",
+      "             **\n",
+      "              *\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "int main() {\n",
+    "  const int len = 15;\n",
+    "  std::string stars( len, '*' );\n",
+    "  display( stars );\n",
+    "  for( unsigned int k = 1; k < stars.length(); k++ ) {\n",
+    "    display( stars.substr( k, std::string::npos ), k );\n",
+    "  }\n",
+    "}\n",
+    "\n",
+    "main()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b518bf97-ab4e-4fbb-90cb-efb9dde87f6f",
+   "metadata": {},
+   "source": [
+    "If we do not know about some standard C++ function or object, we can ask for help:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "79748a7a-6695-4ac0-b1a2-b3de4610d3c6",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<style>\n",
+       "            #pager-container {\n",
+       "                padding: 0;\n",
+       "                margin: 0;\n",
+       "                width: 100%;\n",
+       "                height: 100%;\n",
+       "            }\n",
+       "            .xcpp-iframe-pager {\n",
+       "                padding: 0;\n",
+       "                margin: 0;\n",
+       "                width: 100%;\n",
+       "                height: 100%;\n",
+       "                border: none;\n",
+       "            }\n",
+       "            </style>\n",
+       "            <iframe class=\"xcpp-iframe-pager\" src=\"https://en.cppreference.com/w/cpp/string/basic_string?action=purge\"></iframe>"
+      ],
+      "text/plain": [
+       "https://en.cppreference.com/w/cpp/string/basic_string"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "?std::string"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e381e911-aa5c-43bd-a3d5-2c25a7a0ab3e",
+   "metadata": {},
+   "source": [
+    "### Example #3\n",
+    "We want to implement two functions that return a zero for initialising new variables."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "482d9fcc-e25f-4be2-883c-8c10e7b0ffaf",
+   "metadata": {},
+   "source": [
+    "The magic command **%%file** will write the contents of the cell to the given file"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "a0160540-141d-49a8-a16b-0832deb45111",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Overwriting example.cpp\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%file example.cpp\n",
+    "\n",
+    "int zero() {\n",
+    "  return 0;\n",
+    "}\n",
+    "\n",
+    "double zero() {\n",
+    "  return 0.0;\n",
+    "}\n",
+    "\n",
+    "int main() {\n",
+    "  double dVal = zero();\n",
+    "  int iVal = zero();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5e2ece20-14ea-4eab-b147-c2056abcb54d",
+   "metadata": {},
+   "source": [
+    "Now let's check whether GCC will compile it?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "ecd5b116-b2f7-453f-9bdf-fd4d424f5161",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "example.cpp:6:8: error: ambiguating new declaration of ‘double zero()’\n",
+      "    6 | double zero() {\n",
+      "      |        ^~~~\n",
+      "example.cpp:2:5: note: old declaration ‘int zero()’\n",
+      "    2 | int zero() {\n",
+      "      |     ^~~~\n"
+     ]
+    }
+   ],
+   "source": [
+    "!g++ example.cpp"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2c71fc09-d97c-4f25-ba9e-cd013edda551",
+   "metadata": {},
+   "source": [
+    "Wasn't aware that 'ambiguate' was a verb ;-) Let's see what clang will tell us"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "3cb990eb-aef8-464b-ac85-644c0d7b57c2",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "example.cpp:6:8: error: functions that differ only in their return type cannot be overloaded\n",
+      "double zero() {\n",
+      "~~~~~~ ^\n",
+      "example.cpp:2:5: note: previous definition is here\n",
+      "int zero() {\n",
+      "~~~ ^\n",
+      "1 error generated.\n"
+     ]
+    }
+   ],
+   "source": [
+    "!clang++ example.cpp"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1e494c0f-d7a1-4412-b67b-5911f5d7d46b",
+   "metadata": {},
+   "source": [
+    "Okay, so apparently overloading does not work, for **'functions that differ only in their return type'**.\n",
+    "Well, we might remember that the **signature of a function** consists of the number and type of its arguments, but not its return type.\n",
+    "We can check on that by the following:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "91797c03-d79d-446d-946a-1ecdd8184f44",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Overwriting signature.cpp\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%file signature.cpp\n",
+    "\n",
+    "int getMagnitude( int input ) {\n",
+    "  return input > 0 ? input : -input;\n",
+    "}\n",
+    "\n",
+    "double getMagnitude( double input ) {\n",
+    "  return input > 0.0 ? input : -input;\n",
+    "}\n",
+    "\n",
+    "int getMagnitude( short input ) {\n",
+    "  return input > 0 ? input : -input;\n",
+    "}\n",
+    "\n",
+    "void demo( double dVal, float fVal, int* iPtr ){};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "07ca2086-0fc4-41df-8061-40aa13bc7f67",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!g++ -c signature.cpp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "773be3ed-09bb-48bc-9af6-75a6156db75c",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0000000000000017 T getMagnitude(double)\n",
+      "0000000000000000 T getMagnitude(int)\n",
+      "0000000000000057 T getMagnitude(short)\n",
+      "0000000000000076 T demo(double, float, int*)\n"
+     ]
+    }
+   ],
+   "source": [
+    "!nm -C signature.o"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b12a46e2-5875-401a-9f8e-ae4fdc7b9dfd",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++17",
+   "language": "C++17",
+   "name": "xcpp17"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "17"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/02_Pointers+References.ipynb b/notebooks/02_Pointers+References.ipynb
index 03f67b6..316acdc 100644
--- a/notebooks/02_Pointers+References.ipynb
+++ b/notebooks/02_Pointers+References.ipynb
@@ -1 +1,366 @@
-{"metadata":{"orig_nbformat":4,"language_info":{"codemirror_mode":"text/x-c++src","file_extension":".cpp","mimetype":"text/x-c++src","name":"c++","version":"17"},"kernelspec":{"name":"xcpp17","display_name":"C++17","language":"C++17"}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# References","metadata":{},"id":"eb6a84a9-1411-4a9b-8cbb-c7ed29ecb9c0"},{"cell_type":"code","source":"#include <iostream>\n#include <memory>","metadata":{},"execution_count":1,"outputs":[],"id":"40de00aa-5b48-420d-8743-099cef5d316a"},{"cell_type":"code","source":"void check() {\n    int iVal = 1;\n    int* ptr2int = &iVal;\n    int** ptr2ptr = &ptr2int;\n    int& ref2int = iVal;\n    // int&& ref2ref = ref2int; // this will not work\n    \n    std::cout << \"iVal stores a value of ................. \" << iVal << '\\n';\n    std::cout << \"iVal resides in memory at address ...... \" << std::addressof( iVal ) << \"\\n\\n\";\n\n    std::cout << \"ptr2int stores a value of .............. << \" << ptr2int << '\\n';\n    std::cout << \"ptr2int resides in memory at address ... << \" << &ptr2int << \"\\n\\n\";\n\n    std::cout << \"ptr2ptr stores a value of .............. << \" << ptr2ptr << '\\n';\n    std::cout << \"ptr2ptr resides in memory at address ... << \" << &ptr2ptr << \"\\n\\n\";\n\n    std::cout << \"ref2int stores a value of .............. << \" << ref2int << '\\n';\n    std::cout << \"ref2int resides in memory at address ... << \" << &ref2int << std::endl;\n}","metadata":{},"execution_count":2,"outputs":[],"id":"0579d3c2-3f9d-4904-8762-f1d6cdb2581d"},{"cell_type":"code","source":"check()","metadata":{},"execution_count":3,"outputs":[{"name":"stdout","text":"iVal stores a value of ................. 1\niVal resides in memory at address ...... 0x7fffea96f2ac\n\nptr2int stores a value of .............. << 0x7fffea96f2ac\nptr2int resides in memory at address ... << 0x7fffea96f2a0\n\nptr2ptr stores a value of .............. << 0x7fffea96f2a0\nptr2ptr resides in memory at address ... << 0x7fffea96f298\n\nref2int stores a value of .............. << 1\nref2int resides in memory at address ... << 0x7fffea96f2ac\n","output_type":"stream"}],"id":"3a7034da-2d7f-4429-9853-ffd5e62eefcb"},{"cell_type":"markdown","source":"The last two lines clearly show the difference between a pointer and a reference.\nWhile the pointer is a variable with its own memory location, the reference is only an alias of sorts. It occupies the same place in memory and stores the same value as the object it is bound/initialised to.","metadata":{},"id":"410de220-647d-48f0-93e5-1789d2a72300"},{"cell_type":"markdown","source":"# Dynamic Object Creation","metadata":{},"id":"7fd67f39-e7cf-473b-a316-9d093b97dc7c"},{"cell_type":"markdown","source":" - Often we will only find out how large a problem is during execution of our program.\n - Imagine e.g. that you want to run a Finite Element simulation. Typically you will use a mesh generated by an external meshing program for that. Thus, you cannot say apriorily how much memory space you will need to store the triangles/tetrahedra of that mesh.\n\n - Thus, we need a way to allocate memory at run-time, i.e. during execution of our program.\n - C++ provides the **new expression** for this.","metadata":{},"id":"ff9a0e59-ce0c-4e45-a6fd-55fe94f6953e"},{"cell_type":"code","source":"// Let's check whether this works?\nint main() {\n  int a = new int;\n  a = 2;\n  std::cout << \"a stores \" << a << std::endl;\n}\n\nmain();","metadata":{},"execution_count":4,"outputs":[{"name":"stderr","text":"input_line_10:3:7: error: cannot initialize a variable of type 'int' with an rvalue of type 'int *'\n  int a = new int;\n      ^   ~~~~~~~\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"8adf9d0f-35a5-4c01-b2b1-6ed24733ba00"},{"cell_type":"code","source":"#include <iostream>\n\n// Corrected version\nint main() {\n  int* a = new int;\n  *a = 2;\n  std::cout << \"a stores \" << a << std::endl;\n  std::cout << \"*a stores \" << *a << std::endl;\n    \n  // let's check whether new initialises?\n  double* dPtr = new double;\n    std::cout << \"*dPtr = \" << *dPtr << std::endl;\n     short* sPtr = new short;\n    std::cout << \"*sPtr = \" << *sPtr << std::endl;\n    \n  // no, it does not (at least not for PODs)\n}\n\nmain();","metadata":{},"execution_count":1,"outputs":[{"name":"stdout","text":"a stores 0x55c31b5d3ff0\n*a stores 2\n*dPtr = 4.65886e-310\n*sPtr = 11024\n","output_type":"stream"}],"id":"b6955ae1-ec49-4ddc-8dc6-53d459bd6a4e"},{"cell_type":"code","source":"// Now let's try to dynamically allocate an array\ndouble* array = new double[10];\n\nfor( int k = 0; k < 10; k++ ) {\n    std::cout << \"array[\" << k << \"] = \" << array[k] << '\\n';\n}","metadata":{},"execution_count":2,"outputs":[{"name":"stdout","text":"array[0] = 4.65886e-310\narray[1] = 0\narray[2] = 0\narray[3] = 0\narray[4] = 4.65886e-310\narray[5] = 0\narray[6] = 0\narray[7] = 4.65886e-310\narray[8] = 4.65886e-310\narray[9] = 4.65886e-310\n","output_type":"stream"}],"id":"cdb7efd5-0d40-4278-a19a-17a6d84e6dfd"},{"cell_type":"markdown","source":"### Deletion and Memory Leaks\n - When we dynamically allocate something, we should also take care to delete it, once we no longer need it\n - Otherwise we might generate a **memory leak**\n - Same happens, if we loose the address of the allocated object","metadata":{},"id":"0dc4e4be-11c2-4039-a9de-4ac522969417"},{"cell_type":"code","source":"#include <iostream>\n#include <new>      // for std::nothrow, also comes in indirectly via iostream\n#include <cstdlib>  // for exit(), EXIT_FAILURE\n#include <limits>   // for numeric_limits\n\ndouble* getMem( unsigned long long n ) {\n\n    double* dPtr = nullptr;\n\n    // nothrow avoid throwing an exception if allocation fails;\n    // instead a nullptr is returned\n    dPtr = new( std::nothrow ) double[n];\n\n    // check, if that went smoothly\n    if( dPtr != nullptr ) {\n      std::cout << \"Allocated \" << sizeof(double)*n\n                << \" bytes at address \" << dPtr << std::endl;\n    }\n    else {\n      std::cout << \"\\n *** Problem with memory allocation ***\" << std::endl;\n      std::exit( EXIT_FAILURE );\n    }\n\n    // hand address back\n    return dPtr;\n\n} // (1) dPtr goes out of scope now, but dynamic memory is not deleted!","metadata":{"trusted":true},"execution_count":1,"outputs":[],"id":"2a70c970-aef1-4fe3-a953-6c37fe86438d"},{"cell_type":"code","source":"int main() {\n\n  double* arr = getMem( 100 );\n  std::cout << \"arr starts at \" << arr << std::endl;\n\n  // (1) address is still valid\n  arr[0] = 1.0;\n  delete[] arr;  // delete memory block again, need [] because it's an array\n\n  // ask for too much\n  arr = getMem( std::numeric_limits<unsigned long long>::max() );\n\n}\n\nmain();","metadata":{"trusted":true},"execution_count":null,"outputs":[{"name":"stdout","text":"Allocated 800 bytes at address 0x5603a02f5d60\narr starts at 0x5603a02f5d60\n\n *** Problem with memory allocation ***\n","output_type":"stream"}],"id":"e3a66e21-f10f-4a49-8663-c47cde6ca315"},{"cell_type":"code","source":"#include <iostream>\n\nint main() {\n    int* iPtr = nullptr;\n    \n    for( unsigned int k = 1; k <= 5; ++k ) {\n        iPtr = new int[10];\n        std::cout << \"40 byte block allocated at address \" << iPtr << std::endl;\n    }\n    \n    std::cout << \"deleting memory block with starting address \" << iPtr << std::endl;\n    delete[] iPtr;\n}\n\nmain();","metadata":{"trusted":true},"execution_count":1,"outputs":[{"name":"stdout","text":"40 byte block allocated at address 0x56501213e090\n40 byte block allocated at address 0x5650147437c0\n40 byte block allocated at address 0x56501472e010\n40 byte block allocated at address 0x565014488a70\n40 byte block allocated at address 0x5650140e0fe0\ndeleting memory block with starting address 0x5650140e0fe0\n","output_type":"stream"}],"id":"b2c0e344-1663-444d-898b-162f78af0ca2"},{"cell_type":"markdown","source":"In the above example we have unrecoverably **lost** 4 * 40 = 160 bytes of memory","metadata":{},"id":"63030691-3c76-4ad8-8ca8-450eade595a6"},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[],"id":"69f6ee2d-5622-47bf-a92c-ae4866103428"}]}
\ No newline at end of file
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "eb6a84a9-1411-4a9b-8cbb-c7ed29ecb9c0",
+   "metadata": {},
+   "source": [
+    "# References"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "40de00aa-5b48-420d-8743-099cef5d316a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "#include <memory>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "0579d3c2-3f9d-4904-8762-f1d6cdb2581d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void check() {\n",
+    "    int iVal = 1;\n",
+    "    int* ptr2int = &iVal;\n",
+    "    int** ptr2ptr = &ptr2int;\n",
+    "    int& ref2int = iVal;\n",
+    "    // int&& ref2ref = ref2int; // this will not work\n",
+    "    \n",
+    "    std::cout << \"iVal stores a value of ................. \" << iVal << '\\n';\n",
+    "    std::cout << \"iVal resides in memory at address ...... \" << std::addressof( iVal ) << \"\\n\\n\";\n",
+    "\n",
+    "    std::cout << \"ptr2int stores a value of .............. << \" << ptr2int << '\\n';\n",
+    "    std::cout << \"ptr2int resides in memory at address ... << \" << &ptr2int << \"\\n\\n\";\n",
+    "\n",
+    "    std::cout << \"ptr2ptr stores a value of .............. << \" << ptr2ptr << '\\n';\n",
+    "    std::cout << \"ptr2ptr resides in memory at address ... << \" << &ptr2ptr << \"\\n\\n\";\n",
+    "\n",
+    "    std::cout << \"ref2int stores a value of .............. << \" << ref2int << '\\n';\n",
+    "    std::cout << \"ref2int resides in memory at address ... << \" << &ref2int << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "3a7034da-2d7f-4429-9853-ffd5e62eefcb",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "iVal stores a value of ................. 1\n",
+      "iVal resides in memory at address ...... 0x7ffcaf11206c\n",
+      "\n",
+      "ptr2int stores a value of .............. << 0x7ffcaf11206c\n",
+      "ptr2int resides in memory at address ... << 0x7ffcaf112060\n",
+      "\n",
+      "ptr2ptr stores a value of .............. << 0x7ffcaf112060\n",
+      "ptr2ptr resides in memory at address ... << 0x7ffcaf112058\n",
+      "\n",
+      "ref2int stores a value of .............. << 1\n",
+      "ref2int resides in memory at address ... << 0x7ffcaf11206c\n"
+     ]
+    }
+   ],
+   "source": [
+    "check()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "410de220-647d-48f0-93e5-1789d2a72300",
+   "metadata": {},
+   "source": [
+    "The last two lines clearly show the difference between a pointer and a reference.\n",
+    "While the pointer is a variable with its own memory location, the reference is only an alias of sorts. It occupies the same place in memory and stores the same value as the object it is bound/initialised to."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7fd67f39-e7cf-473b-a316-9d093b97dc7c",
+   "metadata": {},
+   "source": [
+    "# Dynamic Object Creation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ff9a0e59-ce0c-4e45-a6fd-55fe94f6953e",
+   "metadata": {},
+   "source": [
+    " - Often we will only find out how large a problem is during execution of our program.\n",
+    " - Imagine e.g. that you want to run a Finite Element simulation. Typically you will use a mesh generated by an external meshing program for that. Thus, you cannot say apriorily how much memory space you will need to store the triangles/tetrahedra of that mesh.\n",
+    "\n",
+    " - Thus, we need a way to allocate memory at run-time, i.e. during execution of our program.\n",
+    " - C++ provides the **new expression** for this."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "b6955ae1-ec49-4ddc-8dc6-53d459bd6a4e",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Overwriting fubar.cpp\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%file fubar.cpp\n",
+    "\n",
+    "#include <iostream>\n",
+    "\n",
+    "// Corrected version\n",
+    "int main() {\n",
+    "  int* a = new int;\n",
+    "  *a = 2;\n",
+    "  std::cout << \"a stores \" << a << std::endl;\n",
+    "  std::cout << \"*a stores \" << (*a) << std::endl;\n",
+    "    \n",
+    "  // let's check whether new initialises?\n",
+    "  double* dPtr = new double;\n",
+    "    std::cout << \"*dPtr = \" << static_cast< double >(*dPtr) << std::endl;\n",
+    "     short* sPtr = new short;\n",
+    "    std::cout << \"*sPtr = \" << (*sPtr) << std::endl;\n",
+    "    \n",
+    "  // yes, it does (at least for PODs)\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "1e398d12-bbf5-4503-a879-8de1a60a1eb2",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!g++ fubar.cpp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "7ba9cef4-12d1-4dea-8488-064309ac49ac",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "a stores 0x5627fd1a6eb0\n",
+      "*a stores 2\n",
+      "*dPtr = 0\n",
+      "*sPtr = 0\n"
+     ]
+    }
+   ],
+   "source": [
+    "!./a.out"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "cdb7efd5-0d40-4278-a19a-17a6d84e6dfd",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "array[0] = 4.66025e-310\n",
+      "array[1] = 0\n",
+      "array[2] = 2.02369e-320\n",
+      "array[3] = 1.65902e+93\n",
+      "array[4] = 6.01666e+151\n",
+      "array[5] = 1.92102e+170\n",
+      "array[6] = 1.10526e+165\n",
+      "array[7] = 8.90558e+252\n",
+      "array[8] = 1.66843e+151\n",
+      "array[9] = 2.10867e-312\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "// Now let's try to dynamically allocate an array\n",
+    "double* array = new double[10];\n",
+    "\n",
+    "for( int k = 0; k < 10; k++ ) {\n",
+    "    std::cout << \"array[\" << k << \"] = \" << array[k] << '\\n';\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0dc4e4be-11c2-4039-a9de-4ac522969417",
+   "metadata": {},
+   "source": [
+    "### Deletion and Memory Leaks\n",
+    " - When we dynamically allocate something, we should also take care to delete it, once we no longer need it\n",
+    " - Otherwise we might generate a **memory leak**\n",
+    " - Same happens, if we loose the address of the allocated object"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "2a70c970-aef1-4fe3-a953-6c37fe86438d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "#include <new>      // for std::nothrow, also comes in indirectly via iostream\n",
+    "#include <cstdlib>  // for exit(), EXIT_FAILURE\n",
+    "#include <limits>   // for numeric_limits\n",
+    "\n",
+    "double* getMem( unsigned long long n ) {\n",
+    "\n",
+    "    double* dPtr = nullptr;\n",
+    "\n",
+    "    // nothrow avoid throwing an exception if allocation fails;\n",
+    "    // instead a nullptr is returned\n",
+    "    dPtr = new double[n];\n",
+    "\n",
+    "    // check, if that went smoothly\n",
+    "    if( dPtr != nullptr ) {\n",
+    "      std::cout << \"Allocated \" << sizeof(double)*n\n",
+    "                << \" bytes at address \" << dPtr << std::endl;\n",
+    "    }\n",
+    "    else {\n",
+    "      std::cout << \"\\n *** Problem with memory allocation ***\" << std::endl;\n",
+    "      std::exit( EXIT_FAILURE );\n",
+    "    }\n",
+    "\n",
+    "    // hand address back\n",
+    "    return dPtr;\n",
+    "\n",
+    "} // (1) dPtr goes out of scope now, but dynamic memory is not deleted!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "e3a66e21-f10f-4a49-8663-c47cde6ca315",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Allocated 800 bytes at address 0x55ccfc4d53c0\n",
+      "arr starts at 0x55ccfc4d53c0\n"
+     ]
+    },
+    {
+     "ename": "Standard Exception",
+     "evalue": "std::bad_alloc",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: std::bad_alloc"
+     ]
+    }
+   ],
+   "source": [
+    "int main() {\n",
+    "\n",
+    "  double* arr = getMem( 100 );\n",
+    "  std::cout << \"arr starts at \" << arr << std::endl;\n",
+    "\n",
+    "  // (1) address is still valid\n",
+    "  arr[0] = 1.0;\n",
+    "  delete[] arr;  // delete memory block again, need [] because it's an array\n",
+    "\n",
+    "  // ask for too much\n",
+    "  arr = getMem( std::numeric_limits<unsigned long long>::max() );\n",
+    "\n",
+    "}\n",
+    "\n",
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "b2c0e344-1663-444d-898b-162f78af0ca2",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "40 byte block allocated at address 0x55ccfc4d3c50\n",
+      "40 byte block allocated at address 0x55ccfc1425b0\n",
+      "40 byte block allocated at address 0x55ccfc4ea390\n",
+      "40 byte block allocated at address 0x55ccfbeb2040\n",
+      "40 byte block allocated at address 0x55ccfc4d2fb0\n",
+      "deleting memory block with starting address 0x55ccfc4d2fb0\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "int main() {\n",
+    "    int* iPtr = nullptr;\n",
+    "    \n",
+    "    for( unsigned int k = 1; k <= 5; ++k ) {\n",
+    "        iPtr = new int[10];\n",
+    "        std::cout << \"40 byte block allocated at address \" << iPtr << std::endl;\n",
+    "    }\n",
+    "    \n",
+    "    std::cout << \"deleting memory block with starting address \" << iPtr << std::endl;\n",
+    "    delete[] iPtr;\n",
+    "}\n",
+    "\n",
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "63030691-3c76-4ad8-8ca8-450eade595a6",
+   "metadata": {},
+   "source": [
+    "In the above example we have unrecoverably **lost** 4 * 40 = 160 bytes of memory"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "69f6ee2d-5622-47bf-a92c-ae4866103428",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++17",
+   "language": "C++17",
+   "name": "xcpp17"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "17"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/03_ParameterPassing.ipynb b/notebooks/03_ParameterPassing.ipynb
index e48ded8..7cf25ae 100644
--- a/notebooks/03_ParameterPassing.ipynb
+++ b/notebooks/03_ParameterPassing.ipynb
@@ -1 +1,555 @@
-{"metadata":{"orig_nbformat":4,"language_info":{"codemirror_mode":"text/x-c++src","file_extension":".cpp","mimetype":"text/x-c++src","name":"c++","version":"17"},"kernelspec":{"name":"xcpp17","display_name":"C++17","language":"C++17"}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Call-by-Value versus Call-by-Reference","metadata":{},"id":"e7ff4eaa-d800-41b0-b8f9-541d4f8dea11"},{"cell_type":"code","source":"#include <iostream>","metadata":{"trusted":true},"execution_count":1,"outputs":[],"id":"1259a4b8-c4e1-4417-ae0f-fc82ca8bba04"},{"cell_type":"code","source":"void swap( int aLoc, int bLoc ) {\n\n  int aux = aLoc;\n\n  std::cout << \"-> in swap (1): (\" << aLoc << \",\" << bLoc << \")\\n\";\n  aLoc = bLoc;\n  bLoc = aux;\n  std::cout << \"-> in swap (2): (\" << aLoc << \",\" << bLoc << \")\\n\";\n}","metadata":{"trusted":true},"execution_count":2,"outputs":[],"id":"7a9f9c64-4826-41bf-9ae0-694127544a0a"},{"cell_type":"code","source":"int main( void ) {\n\n  int a = 1;\n  int b = 5;\n\n  std::cout << \"in main before swap: (\" << a << \",\" << b << \")\\n\";\n  swap( a, b );\n  std::cout << \"in main after swap:  (\" << a << \",\" << b << \")\\n\";\n}","metadata":{"trusted":true},"execution_count":3,"outputs":[],"id":"628f629d-eaf8-4523-bd3a-c63dc02fde81"},{"cell_type":"code","source":"main();","metadata":{"trusted":true},"execution_count":4,"outputs":[{"name":"stdout","text":"in main before swap: (1,5)\n-> in swap (1): (1,5)\n-> in swap (2): (5,1)\nin main after swap:  (1,5)\n","output_type":"stream"}],"id":"347cce26-5b83-45a9-b951-8db56165683d"},{"cell_type":"markdown","source":"#### Call-by-Value\n- Different strategies exist for passing parameters to subprograms.\n- The C language uses a technique denoted as $\\color{blue}{\\text{call-by-value}}$.\n- The formal parameters in the interface of a function\n   - are local variables existing only in the scope of the function\n   - when the function is called the values of the **arguments are\n     copied into the local variables**\n- Changes to local variables do not affect arguments.","metadata":{},"id":"2ab255de-8324-4e09-b623-c1cb28b28089"},{"cell_type":"markdown","source":"#### Call-by-Reference\n\n- A well-know alternative strategy is denoted as $\\color{red}{\\text{call-by-reference}}$.\n- This is the variant used in the Fortran language family.\n- The formal parameters in the interface of a function\n   - are only placeholders (dummy parameters)\n   - when the function is called they are replaced by memory addresses of  the actual arguments\n- Changes to formal parameters do affect the arguments","metadata":{},"id":"d2d308f1-219f-46ae-961e-b193787e02ea"},{"cell_type":"markdown","source":"In C/C++ we can *emulate* call-by-reference with the help of pointers","metadata":{},"id":"e4413584-2f76-44ef-982d-c067bedf4a2c"},{"cell_type":"code","source":"void swapEm( int* ap, int* bp ) {\n\n  int aux = *ap;\n\n  std::cout << \"-> in swap (1): (\" << *ap << \",\" << *bp << \")\\n\";\n  *ap = *bp;\n  *bp = aux;\n  std::cout << \"-> in swap (2): (\" << *ap << \",\" << *bp << \")\\n\";\n}","metadata":{"trusted":true},"execution_count":5,"outputs":[],"id":"a5dea161-dffb-46d0-8146-523d5b340912"},{"cell_type":"code","source":"int main( void ) {\n\n  int a = 1;\n  int b = 5;\n\n  std::cout << \"in main before swap: (\" << a << \",\" << b << \")\\n\";\n  swapEm( &a, &b );\n  std::cout << \"in main after swap:  (\" << a << \",\" << b << \")\\n\";\n}","metadata":{"trusted":true},"execution_count":6,"outputs":[],"id":"16ec48e9-83af-4126-82e8-6eabae87b057"},{"cell_type":"code","source":"main();","metadata":{"trusted":true},"execution_count":7,"outputs":[{"name":"stdout","text":"in main before swap: (1,5)\n-> in swap (1): (1,5)\n-> in swap (2): (5,1)\nin main after swap:  (5,1)\n","output_type":"stream"}],"id":"33c5b821-9e19-4660-9ab5-a2e4e7ebeb37"},{"cell_type":"markdown","source":"Now working with pointers means we always need to do perform address computations and dereferencing to work with the arguments.\n\nIn C++ we can directly use call-by-reference using references","metadata":{},"id":"08427a4a-65a8-4171-9c1d-e445cec1593f"},{"cell_type":"code","source":"void swapCPP( int& aRef, int& bRef ) {\n\n  int aux = aRef;\n\n  std::cout << \"-> in swap (1): (\" << aRef << \",\" << bRef << \")\\n\";\n  aRef = bRef;\n  bRef = aux;\n  std::cout << \"-> in swap (2): (\" << aRef << \",\" << bRef << \")\\n\";\n}","metadata":{"trusted":true},"execution_count":8,"outputs":[],"id":"0b0a1432-7b59-4d16-ac98-24780094db21"},{"cell_type":"code","source":"int main( void ) {\n\n  int a = 1;\n  int b = 5;\n\n  std::cout << \"in main before swap: (\" << a << \",\" << b << \")\\n\";\n  swapCPP( a, b );\n  std::cout << \"in main after swap:  (\" << a << \",\" << b << \")\\n\";\n}","metadata":{"trusted":true},"execution_count":9,"outputs":[],"id":"63e355ff-e53e-4d14-ad22-486abbbe57b4"},{"cell_type":"code","source":"main();","metadata":{"trusted":true},"execution_count":10,"outputs":[{"name":"stdout","text":"in main before swap: (1,5)\n-> in swap (1): (1,5)\n-> in swap (2): (5,1)\nin main after swap:  (5,1)\n","output_type":"stream"}],"id":"d1334cfa-4559-4320-8fc9-9ec588544c4a"},{"cell_type":"markdown","source":"### Language Overview:","metadata":{},"id":"7155c4c4-2b9b-452e-8e97-db5aaebb806c"},{"cell_type":"markdown","source":"- The languages currently most often used in Computational Science use different approaches \n| language | supported mechanics               |\n|:--------:|-----------------------------------|\n| C        | call-by-value                     |\n| Fortran  | call-by-reference                 |\n| C++      | call-by-value & call-by-reference |\n| Python   | call-by-sharing/object/assignment |\n- Python: everything is an object, either mutable or immutable and no variables exist (only names)\n- References in C++ cannot be copied","metadata":{"tags":[]},"id":"87403469-d884-4c95-a100-40b8d5de334d"},{"cell_type":"code","source":"#include <vector>\n\n// create a vector of ints\nstd::vector< int > a = {1,3,7,9};","metadata":{"trusted":true},"execution_count":11,"outputs":[],"id":"b8f3e2f7-5659-4d4b-aa3c-73a879eb0caa"},{"cell_type":"code","source":"a","metadata":{"trusted":true},"execution_count":12,"outputs":[{"execution_count":12,"output_type":"execute_result","data":{"text/plain":"{ 1, 3, 7, 9 }"},"metadata":{}}],"id":"211a4a4d-83e1-4ed1-9a20-62b099df03d4"},{"cell_type":"code","source":"a[0] = -1;         // change first element by direct access\na.push_back( 11 ); // append element at the end\na","metadata":{"trusted":true},"execution_count":13,"outputs":[{"execution_count":13,"output_type":"execute_result","data":{"text/plain":"{ -1, 3, 7, 9, 11 }"},"metadata":{}}],"id":"acdec801-802f-4693-91f7-25deb3f87f13"},{"cell_type":"code","source":"#include <iostream>\n#include <vector>\n\nvoid test() {\n  // note that the std::vector stores copies\n  int val = 10;\n  std::vector< int > foo;\n  foo.push_back( val );\n  foo[0] = 2;\n  std::cout << foo[0] << std::endl;\n  std::cout << val;\n}\n\ntest()","metadata":{"trusted":true},"execution_count":14,"outputs":[{"name":"stdout","text":"2\n10","output_type":"stream"}],"id":"e2ffe5d4-e4f9-4fff-956e-ae35238b2d96"},{"cell_type":"code","source":"// create a vector of pointers to int\nstd::vector< int* > ptrVec;\n\n// try to create a vector of references to int\n// std::vector< int& > fail;","metadata":{"trusted":true},"execution_count":15,"outputs":[],"id":"41e83505-e0da-4251-97c5-34c0b7f9b3fa"},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[],"id":"8555c6be-c957-46ed-9705-3a96d8349a36"}]}
\ No newline at end of file
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "e7ff4eaa-d800-41b0-b8f9-541d4f8dea11",
+   "metadata": {},
+   "source": [
+    "# Call-by-Value versus Call-by-Reference"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "7a9f9c64-4826-41bf-9ae0-694127544a0a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "09ae17ea-ed58-49c5-8b90-d8d97bd76eb5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void swap( int aLoc, int bLoc ) {\n",
+    "\n",
+    "  int aux = aLoc;\n",
+    "\n",
+    "  std::cout << \"-> in swap (1): (\" << aLoc << \",\" << bLoc << \")\\n\";\n",
+    "  aLoc = bLoc;\n",
+    "  bLoc = aux;\n",
+    "  std::cout << \"-> in swap (2): (\" << aLoc << \",\" << bLoc << \")\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "628f629d-eaf8-4523-bd3a-c63dc02fde81",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main( void ) {\n",
+    "\n",
+    "  int a = 1;\n",
+    "  int b = 5;\n",
+    "\n",
+    "  std::cout << \"in main before swap: (\" << a << \",\" << b << \")\\n\";\n",
+    "  swap( a, b );\n",
+    "  std::cout << \"in main after swap:  (\" << a << \",\" << b << \")\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "347cce26-5b83-45a9-b951-8db56165683d",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "in main before swap: (1,5)\n",
+      "-> in swap (1): (1,5)\n",
+      "-> in swap (2): (5,1)\n",
+      "in main after swap:  (1,5)\n"
+     ]
+    }
+   ],
+   "source": [
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2ab255de-8324-4e09-b623-c1cb28b28089",
+   "metadata": {},
+   "source": [
+    "#### Call-by-Value\n",
+    "- Different strategies exist for passing parameters to subprograms.\n",
+    "- The C language uses a technique denoted as $\\color{blue}{\\text{call-by-value}}$.\n",
+    "- The formal parameters in the interface of a function\n",
+    "   - are local variables existing only in the scope of the function\n",
+    "   - when the function is called the values of the **arguments are\n",
+    "     copied into the local variables**\n",
+    "- Changes to local variables do not affect arguments."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d2d308f1-219f-46ae-961e-b193787e02ea",
+   "metadata": {},
+   "source": [
+    "#### Call-by-Reference\n",
+    "\n",
+    "- A well-know alternative strategy is denoted as $\\color{red}{\\text{call-by-reference}}$.\n",
+    "- This is the variant used in the Fortran language family.\n",
+    "- The formal parameters in the interface of a function\n",
+    "   - are only placeholders (dummy parameters)\n",
+    "   - when the function is called they are replaced by memory addresses of  the actual arguments\n",
+    "- Changes to formal parameters do affect the arguments"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e4413584-2f76-44ef-982d-c067bedf4a2c",
+   "metadata": {},
+   "source": [
+    "In C/C++ we can *emulate* call-by-reference with the help of pointers"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "a5dea161-dffb-46d0-8146-523d5b340912",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void swapEm( int* ap, int* bp ) {\n",
+    "\n",
+    "  int aux = *ap;\n",
+    "\n",
+    "  std::cout << \"-> in swap (1): (\" << *ap << \",\" << *bp << \")\\n\";\n",
+    "  *ap = *bp;\n",
+    "  *bp = aux;\n",
+    "  std::cout << \"-> in swap (2): (\" << *ap << \",\" << *bp << \")\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "16ec48e9-83af-4126-82e8-6eabae87b057",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main( void ) {\n",
+    "\n",
+    "  int a = 1;\n",
+    "  int b = 5;\n",
+    "\n",
+    "  std::cout << \"in main before swap: (\" << a << \",\" << b << \")\\n\";\n",
+    "  swapEm( &a, &b );\n",
+    "  std::cout << \"in main after swap:  (\" << a << \",\" << b << \")\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "33c5b821-9e19-4660-9ab5-a2e4e7ebeb37",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "in main before swap: (1,5)\n",
+      "-> in swap (1): (1,5)\n",
+      "-> in swap (2): (5,1)\n",
+      "in main after swap:  (5,1)\n"
+     ]
+    }
+   ],
+   "source": [
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "08427a4a-65a8-4171-9c1d-e445cec1593f",
+   "metadata": {},
+   "source": [
+    "Now working with pointers means we always need to do perform address computations and dereferencing to work with the arguments.\n",
+    "\n",
+    "In C++ we can directly use call-by-reference using references"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "0b0a1432-7b59-4d16-ac98-24780094db21",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void swapCPP( int& aRef, int& bRef ) {\n",
+    "\n",
+    "  int aux = aRef;\n",
+    "\n",
+    "  std::cout << \"-> in swap (1): (\" << aRef << \",\" << bRef << \")\\n\";\n",
+    "  aRef = bRef;\n",
+    "  bRef = aux;\n",
+    "  std::cout << \"-> in swap (2): (\" << aRef << \",\" << bRef << \")\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "63e355ff-e53e-4d14-ad22-486abbbe57b4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main( void ) {\n",
+    "\n",
+    "  int a = 1;\n",
+    "  int b = 5;\n",
+    "\n",
+    "  std::cout << \"in main before swap: (\" << a << \",\" << b << \")\\n\";\n",
+    "  swapCPP( a, b );\n",
+    "  std::cout << \"in main after swap:  (\" << a << \",\" << b << \")\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "d1334cfa-4559-4320-8fc9-9ec588544c4a",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "in main before swap: (1,5)\n",
+      "-> in swap (1): (1,5)\n",
+      "-> in swap (2): (5,1)\n",
+      "in main after swap:  (5,1)\n"
+     ]
+    }
+   ],
+   "source": [
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7155c4c4-2b9b-452e-8e97-db5aaebb806c",
+   "metadata": {},
+   "source": [
+    "### Language Overview:"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "87403469-d884-4c95-a100-40b8d5de334d",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "- The languages currently most often used in Computational Science use different approaches \n",
+    "| language | supported mechanics               |\n",
+    "|:--------:|-----------------------------------|\n",
+    "| C        | call-by-value                     |\n",
+    "| Fortran  | call-by-reference                 |\n",
+    "| C++      | call-by-value & call-by-reference |\n",
+    "| Python   | call-by-sharing/object/assignment |\n",
+    "- Python: everything is an object, either mutable or immutable and no variables exist (only names)\n",
+    "- References in C++ cannot be copied"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "b8f3e2f7-5659-4d4b-aa3c-73a879eb0caa",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "\n",
+    "// create a vector of ints\n",
+    "std::vector< int > a = {1,3,7,9};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "211a4a4d-83e1-4ed1-9a20-62b099df03d4",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 1, 3, 7, 9 }"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "id": "acdec801-802f-4693-91f7-25deb3f87f13",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ -1, 3, 7, 9, 11 }"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a[0] = -1;         // change first element by direct access\n",
+    "a.push_back( 11 ); // append element at the end\n",
+    "a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "e2ffe5d4-e4f9-4fff-956e-ae35238b2d96",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2\n",
+      "10"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "#include <vector>\n",
+    "\n",
+    "void test() {\n",
+    "  // note that the std::vector stores copies\n",
+    "  int val = 10;\n",
+    "  std::vector< int > foo;\n",
+    "  foo.push_back( val );\n",
+    "  foo[0] = 2;\n",
+    "  std::cout << foo[0] << std::endl;\n",
+    "  std::cout << val;\n",
+    "}\n",
+    "\n",
+    "test()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "41e83505-e0da-4251-97c5-34c0b7f9b3fa",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "In file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:61:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/unordered_map:40:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/allocator.h:46:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/x86_64-conda-linux-gnu/bits/c++allocator.h:33:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/new_allocator.h:62:18: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'pointer' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      typedef _Tp*       pointer;\n",
+      "\u001b[0;1;32m                 ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/allocator.h:122:30: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class '__gnu_cxx::new_allocator<int &>' requested here\u001b[0m\n",
+      "    class allocator : public __allocator_base<_Tp>\n",
+      "\u001b[0;1;32m                             ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/alloc_traits.h:47:47: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::allocator<int &>' requested here\u001b[0m\n",
+      "template<typename _Alloc, typename = typename _Alloc::value_type>\n",
+      "\u001b[0;1;32m                                              ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:86:35: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of default argument for '__alloc_traits<std::allocator<int &> >' required here\u001b[0m\n",
+      "      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template\n",
+      "\u001b[0;1;32m                                  ^~~~~~~~~~~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:389:30: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::_Vector_base<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "    class vector : protected _Vector_base<_Tp, _Alloc>\n",
+      "\u001b[0;1;32m                             ^\n",
+      "\u001b[0m\u001b[1minput_line_33:5:21: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::vector<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "std::vector< int& > fail;\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:61:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/unordered_map:40:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/allocator.h:46:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/x86_64-conda-linux-gnu/bits/c++allocator.h:33:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/new_allocator.h:63:24: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'const_pointer' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      typedef const _Tp* const_pointer;\n",
+      "\u001b[0;1;32m                       ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/new_allocator.h:96:7: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mmultiple overloads of 'address' instantiate to the same signature '__gnu_cxx::new_allocator<int &>::const_pointer (__gnu_cxx::new_allocator<int &>::const_reference) const noexcept' (aka 'int (int &) const noexcept')\u001b[0m\n",
+      "      address(const_reference __x) const _GLIBCXX_NOEXCEPT\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/new_allocator.h:92:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mprevious declaration is here\u001b[0m\n",
+      "      address(reference __x) const _GLIBCXX_NOEXCEPT\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/new_allocator.h:102:29: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'allocate' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      _GLIBCXX_NODISCARD _Tp*\n",
+      "\u001b[0;1;32m                            ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/new_allocator.h:126:21: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'__p' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      deallocate(_Tp* __p, size_type __t)\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:61:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/unordered_map:40:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/allocator.h:131:18: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'pointer' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      typedef _Tp*       pointer;\n",
+      "\u001b[0;1;32m                 ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/alloc_traits.h:47:47: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::allocator<int &>' requested here\u001b[0m\n",
+      "template<typename _Alloc, typename = typename _Alloc::value_type>\n",
+      "\u001b[0;1;32m                                              ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:86:35: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of default argument for '__alloc_traits<std::allocator<int &> >' required here\u001b[0m\n",
+      "      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template\n",
+      "\u001b[0;1;32m                                  ^~~~~~~~~~~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:389:30: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::_Vector_base<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "    class vector : protected _Vector_base<_Tp, _Alloc>\n",
+      "\u001b[0;1;32m                             ^\n",
+      "\u001b[0m\u001b[1minput_line_33:5:21: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::vector<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "std::vector< int& > fail;\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:61:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/unordered_map:40:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/allocator.h:132:24: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'const_pointer' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      typedef const _Tp* const_pointer;\n",
+      "\u001b[0;1;32m                       ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:61:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/unordered_map:41:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/alloc_traits.h:47:47: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mtype 'int' cannot be used prior to '::' because it has no members\u001b[0m\n",
+      "template<typename _Alloc, typename = typename _Alloc::value_type>\n",
+      "\u001b[0;1;32m                                              ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:88:35: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of default argument for '__alloc_traits<int>' required here\u001b[0m\n",
+      "      typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer\n",
+      "\u001b[0;1;32m                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:389:30: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::_Vector_base<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "    class vector : protected _Vector_base<_Tp, _Alloc>\n",
+      "\u001b[0;1;32m                             ^\n",
+      "\u001b[0m\u001b[1minput_line_33:5:21: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::vector<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "std::vector< int& > fail;\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:62:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/vector:67:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:129:11: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mbase specifier must name a class\u001b[0m\n",
+      "        : public _Tp_alloc_type, public _Vector_impl_data\n",
+      "\u001b[0;1;32m          ~~~~~~~^~~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:340:20: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of member class 'std::_Vector_base<int &, std::allocator<int &> >::_Vector_impl' requested here\u001b[0m\n",
+      "      _Vector_impl _M_impl;\n",
+      "\u001b[0;1;32m                   ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:389:30: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::_Vector_base<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "    class vector : protected _Vector_base<_Tp, _Alloc>\n",
+      "\u001b[0;1;32m                             ^\n",
+      "\u001b[0m\u001b[1minput_line_33:5:21: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::vector<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "std::vector< int& > fail;\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:61:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/unordered_map:41:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ext/alloc_traits.h:47:47: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mtype 'int' cannot be used prior to '::' because it has no members\u001b[0m\n",
+      "template<typename _Alloc, typename = typename _Alloc::value_type>\n",
+      "\u001b[0;1;32m                                              ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:411:26: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of default argument for '__alloc_traits<int>' required here\u001b[0m\n",
+      "      typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;\n",
+      "\u001b[0;1;32m                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1minput_line_33:5:21: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::vector<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "std::vector< int& > fail;\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:62:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/vector:67:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:1167:10: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'data' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      _Tp*\n",
+      "\u001b[0;1;32m         ^\n",
+      "\u001b[0m\u001b[1minput_line_33:5:21: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of template class 'std::vector<int &, std::allocator<int &> >' requested here\u001b[0m\n",
+      "std::vector< int& > fail;\n",
+      "\u001b[0;1;32m                    ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:13:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/functional:62:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/vector:67:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:1171:16: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'data' declared as a pointer to a reference of type 'int &'\u001b[0m\n",
+      "      const _Tp*\n",
+      "\u001b[0;1;32m               ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:1203:7: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mmultiple overloads of 'push_back' instantiate to the same signature 'void (int &)'\u001b[0m\n",
+      "      push_back(value_type&& __x)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:1187:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mprevious declaration is here\u001b[0m\n",
+      "      push_back(const value_type& __x)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:1293:7: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mmultiple overloads of 'insert' instantiate to the same signature 'std::vector<int &, std::allocator<int &> >::iterator (std::vector<int &, std::allocator<int &> >::const_iterator, int &)' (aka '__normal_iterator<int, std::vector<int &, std::allocator<int &> > > (__normal_iterator<int, std::vector<int &, std::allocator<int &> > >, int &)')\u001b[0m\n",
+      "      insert(const_iterator __position, value_type&& __x)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/bits/stl_vector.h:1263:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mprevious declaration is here\u001b[0m\n",
+      "      insert(const_iterator __position, const value_type& __x);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "// create a vector of pointers to int\n",
+    "std::vector< int* > ptrVec;\n",
+    "\n",
+    "// try to create a vector of references to int\n",
+    "std::vector< int& > fail;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8555c6be-c957-46ed-9705-3a96d8349a36",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++17",
+   "language": "C++17",
+   "name": "xcpp17"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "17"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/04_Classes+Objects.ipynb b/notebooks/04_Classes+Objects.ipynb
index 4750860..fd14a7d 100644
--- a/notebooks/04_Classes+Objects.ipynb
+++ b/notebooks/04_Classes+Objects.ipynb
@@ -94,7 +94,7 @@
     "\n",
     "|            | class | struct |\n",
     "|:----------:|:-----:|:------:|\n",
-    "| default is:|private| public |"
+    "| **default is:** |private| public |"
    ]
   },
   {
@@ -355,7 +355,9 @@
     "                      << \" memb_ = \" << memb_ << std::endl;\n",
     "        }\n",
     "\n",
-    "        myClass() : myClass(0) {}\n",
+    "        myClass() : myClass(0) {\n",
+    "            std::cout << \"Executing body of default c'tor\" << std::endl;\n",
+    "        }\n",
     "        \n",
     "    private:\n",
     "        int memb_;\n",
@@ -445,7 +447,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 12,
    "id": "f33e5eef-b396-4bfc-8031-f21b33839611",
    "metadata": {},
    "outputs": [],
@@ -496,7 +498,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 13,
    "id": "e2f2ac16-a0df-4f6c-816a-cb47420f4989",
    "metadata": {},
    "outputs": [],
@@ -508,7 +510,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 14,
    "id": "7c06f924-8412-449c-a5b5-a56b1df2ff2b",
    "metadata": {},
    "outputs": [
@@ -534,7 +536,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 15,
    "id": "102897af-957e-43b7-a959-eb6ee468f35d",
    "metadata": {},
    "outputs": [],
@@ -585,7 +587,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 16,
    "id": "adcac578-0bca-4aed-8d13-4514826dd0e7",
    "metadata": {},
    "outputs": [
@@ -611,15 +613,15 @@
    "id": "1a74105b-5453-49ab-aeed-e0371809fc52",
    "metadata": {},
    "source": [
-    "Our VectorClass currently is pretty useless, since we cannot manipulate the values of the vector entries. Making vec_ public would break encapsulation. Instead let's\n",
-    "- overload the [ ] for providing one-based access\n",
+    "Our VectorClass currently is pretty useless, since we cannot manipulate the values of the vector entries. Making `vec_` public would break encapsulation. Instead let's\n",
+    "- overload the `[ ]` operator for providing one-based access\n",
     "- add a getter method for the dimension\n",
     "- add a member function to pretty-print the vector's entries"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 17,
    "id": "a32eb08a-822a-4b83-b3d0-6de281acffba",
    "metadata": {},
    "outputs": [],
@@ -664,7 +666,7 @@
     "        // overload the [] for accessing individual entries\n",
     "        double& operator[] ( unsigned int index ) {\n",
     "            assert( index != 0 && index <= dim_ );\n",
-    "            return vec_[index-1];\n",
+    "            return vec_[index-1u];\n",
     "        }\n",
     "\n",
     "        // pretty print vector to given output stream\n",
@@ -685,7 +687,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 18,
    "id": "4eb50e73-21f5-4669-9464-32f11d958732",
    "metadata": {},
    "outputs": [
@@ -732,7 +734,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 19,
    "id": "cdfde2f9-fafc-4a9f-99b7-4952720e4521",
    "metadata": {},
    "outputs": [
@@ -854,7 +856,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 20,
    "id": "f9331dc3-19ff-44a2-a8f5-6e258f9266d2",
    "metadata": {},
    "outputs": [],
@@ -864,7 +866,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 21,
    "id": "4f4d196d-761d-40e1-9d08-5df87307476b",
    "metadata": {},
    "outputs": [
@@ -968,7 +970,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 22,
    "id": "def80c0f-89b6-4e00-995a-14b8e800975c",
    "metadata": {},
    "outputs": [
@@ -1090,7 +1092,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 23,
    "id": "473de9eb-b04c-4087-8444-8d4b3c4c9fb8",
    "metadata": {},
    "outputs": [
@@ -1133,23 +1135,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
-   "id": "30eccd22-8c5e-4062-a1d1-8006981aae99",
+   "execution_count": 2,
+   "id": "009c7af1-bf59-4203-8622-9cf8c9cb4639",
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "\u001b[1minput_line_47:61:45: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno viable overloaded operator[] for type 'const VectorClass'\u001b[0m\n",
+      "\u001b[1minput_line_9:61:45: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno viable overloaded operator[] for type 'const VectorClass'\u001b[0m\n",
       "                this->operator[](k) += other[k];\n",
       "\u001b[0;1;32m                                       ~~~~~^~\n",
-      "\u001b[0m\u001b[1minput_line_47:32:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: 'this' argument has type 'const VectorClass', but method is not marked const\u001b[0m\n",
+      "\u001b[0m\u001b[1minput_line_9:32:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: 'this' argument has type 'const VectorClass', but method is not marked const\u001b[0m\n",
       "        double& operator[] ( unsigned int index ){\n",
       "\u001b[0;1;32m                ^\n",
-      "\u001b[0m\u001b[1minput_line_47:71:13: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mfunction definition is not allowed here\u001b[0m\n",
-      " int main() {\n",
-      "\u001b[0;1;32m            ^\n",
       "\u001b[0m"
      ]
     },
@@ -1227,7 +1226,7 @@
     "        void add( const VectorClass& other ) {\n",
     "\n",
     "            // make sure that input vector has correct length\n",
-    "            assert( other.getDim() == dim_ );\n",
+    "            assert( other.dim_ == dim_ );\n",
     "            // for( unsigned int k = 0; k < dim_; k++ ) {\n",
     "            //     vec_[k] += other[k+1];\n",
     "            // }\n",
@@ -1240,31 +1239,7 @@
     "        unsigned int dim_;   // dimension of vector\n",
     "        double* vec_;        // entries of vector\n",
     "\n",
-    "};\n",
-    "\n",
-    "// Modify driver a little bit\n",
-    "int main() {\n",
-    "\n",
-    "    const unsigned int dim = 10;\n",
-    "  \n",
-    "    // set up 1st vector\n",
-    "    VectorClass myVec( dim );\n",
-    "    for( unsigned int idx = 1; idx <= dim; idx ++ ) {\n",
-    "      myVec[ idx ] = static_cast<double>( dim - idx + 1 );\n",
-    "    }\n",
-    "    myVec.print( std::cout );\n",
-    "    \n",
-    "    // set up 2nd vector\n",
-    "    VectorClass other( dim );\n",
-    "    for( unsigned int idx = 1; idx <= dim; idx ++ ) {\n",
-    "      other[ idx ] = static_cast<double>( idx );\n",
-    "    }\n",
-    "    other.print( std::cout );\n",
-    "    \n",
-    "    // add the 2nd to the 1st\n",
-    "    myVec.add( other );\n",
-    "    myVec.print();\n",
-    "}"
+    "};"
    ]
   },
   {
@@ -1280,7 +1255,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": 3,
    "id": "15b02a70-a496-4098-a446-9a60ee30b116",
    "metadata": {},
    "outputs": [
@@ -1288,21 +1263,202 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "\u001b[1minput_line_49:41:23: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mfunctions that differ only in their return type cannot be overloaded\u001b[0m\n",
+      "\u001b[1minput_line_11:41:23: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mfunctions that differ only in their return type cannot be overloaded\u001b[0m\n",
       "        const double& operator[] ( unsigned int index ) {\n",
       "\u001b[0;1;32m              ~~~~~~~ ^\n",
-      "\u001b[0m\u001b[1minput_line_49:35:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mprevious definition is here\u001b[0m\n",
+      "\u001b[0m\u001b[1minput_line_11:35:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mprevious definition is here\u001b[0m\n",
       "        double& operator[] ( unsigned int index ){\n",
       "\u001b[0;1;32m        ~~~~~~~ ^\n",
-      "\u001b[0m\u001b[1minput_line_49:70:45: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno viable overloaded operator[] for type 'const VectorClass'\u001b[0m\n",
+      "\u001b[0m\u001b[1minput_line_11:15:23: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types 'basic_ostream<char, std::char_traits<char> >' and 'unsigned int')\u001b[0m\n",
+      "                      << dim_ << std::endl;\n",
+      "\u001b[0;1;32m                      ^  ~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:166:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:174:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(bool __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:178:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(short __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:181:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned short __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:189:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(int __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:201:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:205:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:224:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(float __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:232:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long double __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:517:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:511:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _CharT = char, _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:523:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:528:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1minput_line_11:28:23: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types 'basic_ostream<char, std::char_traits<char> >' and 'unsigned long')\u001b[0m\n",
+      "                      << dim_ * sizeof(double)\n",
+      "\u001b[0;1;32m                      ^  ~~~~~~~~~~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:166:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:174:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(bool __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:178:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(short __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:181:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned short __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:189:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(int __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:201:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:205:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:224:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(float __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:232:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long double __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:517:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:511:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _CharT = char, _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:523:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:528:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1minput_line_11:50:20: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types 'std::ostream' (aka 'basic_ostream<char>') and 'double')\u001b[0m\n",
+      "                os << vec_[k] << \", \";\n",
+      "\u001b[0;1;32m                ~~ ^  ~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:166:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:174:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(bool __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:178:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(short __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:181:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned short __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:189:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(int __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:201:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:205:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:224:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(float __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:232:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long double __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:517:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:511:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _CharT = char, _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:523:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:528:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1minput_line_11:52:16: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types 'std::ostream' (aka 'basic_ostream<char>') and 'double')\u001b[0m\n",
+      "            os << vec_[dim_-1] << \")\" << std::endl;\n",
+      "\u001b[0;1;32m            ~~ ^  ~~~~~~~~~~~~\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:166:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:174:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(bool __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:178:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(short __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:181:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned short __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:189:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(int __n);\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:201:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:205:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(unsigned long long __n)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:224:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(float __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:232:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function\u001b[0m\n",
+      "      operator<<(long double __f)\n",
+      "\u001b[0;1;32m      ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:517:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:511:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _CharT = char, _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:523:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:528:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function [with _Traits = std::char_traits<char>]\u001b[0m\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n",
+      "\u001b[0;1;32m    ^\n",
+      "\u001b[0m\u001b[1minput_line_11:70:45: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno viable overloaded operator[] for type 'const VectorClass'\u001b[0m\n",
       "                this->operator[](k) += other[k];\n",
       "\u001b[0;1;32m                                       ~~~~~^~\n",
-      "\u001b[0m\u001b[1minput_line_49:35:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: 'this' argument has type 'const VectorClass', but method is not marked const\u001b[0m\n",
+      "\u001b[0m\u001b[1minput_line_11:35:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: 'this' argument has type 'const VectorClass', but method is not marked const\u001b[0m\n",
       "        double& operator[] ( unsigned int index ){\n",
       "\u001b[0;1;32m                ^\n",
-      "\u001b[0m\u001b[1minput_line_49:80:13: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mfunction definition is not allowed here\u001b[0m\n",
+      "\u001b[0m\u001b[1minput_line_11:80:13: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mfunction definition is not allowed here\u001b[0m\n",
       " int main() {\n",
       "\u001b[0;1;32m            ^\n",
+      "\u001b[0mIn file included from input_line_5:1:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xinterpreter.hpp:17:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/xeus/xcomm.hpp:19:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/nlohmann/json.hpp:41:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/nlohmann/detail/input/binary_reader.hpp:25:\n",
+      "In file included from /home/student/micromamba/envs/xeus/include/nlohmann/detail/input/input_adapters.hpp:23:\n",
+      "In file included from /home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/istream:39:\n",
+      "\u001b[1m/home/student/micromamba/envs/xeus/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/10.4.0/ostream:609:8: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno member named 'setstate' in 'std::basic_ostream<char>'\u001b[0m\n",
+      "        __out.setstate(ios_base::badbit);\n",
+      "\u001b[0;1;32m        ~~~~~ ^\n",
+      "\u001b[0m\u001b[1minput_line_11:14:23: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\u001b[0m\n",
+      "            std::cout << \"An instance of VectorClass was generated. dim_ = \"\n",
+      "\u001b[0;1;32m                      ^\n",
       "\u001b[0m"
      ]
     },
@@ -1390,7 +1546,7 @@
     "            // make sure that input vector has correct length\n",
     "            assert( other.getDim() == dim_ );\n",
     "            // for( unsigned int k = 0; k < dim_; k++ ) {\n",
-    "            //     vec_[k] += other[k+1];\n",
+    "            //     vec_[k] += other.vec_[k];\n",
     "            // }\n",
     "            for( unsigned int k = 1; k <= dim_; k++ ) {\n",
     "                this->operator[](k) += other[k];\n",
@@ -1447,7 +1603,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 1,
    "id": "0b2a852d-2a07-4f2a-85d2-7833051474d7",
    "metadata": {},
    "outputs": [],
@@ -1542,7 +1698,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 2,
    "id": "81aeb13c-be8f-4e15-b7d7-acffb4a575eb",
    "metadata": {},
    "outputs": [],
@@ -1573,7 +1729,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 38,
+   "execution_count": 3,
    "id": "77177a38-424a-4558-8836-9c6f95bdd7c0",
    "metadata": {},
    "outputs": [
@@ -1586,9 +1742,9 @@
       "An instance of VectorClass was generated. dim_ = 10\n",
       "(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n",
       "(11, 11, 11, 11, 11, 11, 11, 11, 11, 11)\n",
-      "Going to delete memory starting at address 0x5627a2271680\n",
+      "Going to delete memory starting at address 0x55720f9f5410\n",
       "An instance of VectorClass was destroyed and 80 bytes freed.\n",
-      "Going to delete memory starting at address 0x5627a226b850\n",
+      "Going to delete memory starting at address 0x55720f60df30\n",
       "An instance of VectorClass was destroyed and 80 bytes freed.\n"
      ]
     }
@@ -1620,18 +1776,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 39,
+   "execution_count": null,
    "id": "867de208-5492-44c0-bf04-7ac9f868908f",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Writing splitA.hpp\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "%%file splitA.hpp\n",
     "\n",
@@ -1642,7 +1790,8 @@
     "  std::string name_;\n",
     "\n",
     "  public:\n",
-    "  void setName( const char* name );\n",
+    "  // void setName( const char* name );\n",
+    "  void setName( const std::string& name );\n",
     "  void printName();\n",
     "\n",
     "};"
@@ -1650,18 +1799,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": null,
    "id": "639efb26-6150-4cdf-aef4-b962ba86a6a3",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Writing splitA.cpp\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "%%file splitA.cpp\n",
     "\n",
@@ -1669,25 +1810,17 @@
     "#include \"splitA.hpp\"\n",
     "\n",
     "// Need to prefix the member function name with the class name\n",
-    "void A::setName( const char* name ) {\n",
+    "void A::setName( const std::string& name ) {\n",
     "  name_ = name;\n",
     "}"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": null,
    "id": "3ed47b3b-3b45-4fc3-ab31-655915b41251",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Writing splitB.cpp\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "%%file splitB.cpp\n",
     "\n",
@@ -1706,7 +1839,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 42,
+   "execution_count": null,
    "id": "2c897fb0-b3a2-4617-8b92-79dbaaff6b8b",
    "metadata": {},
    "outputs": [],
@@ -1721,6 +1854,26 @@
    "id": "782da53e-ca04-42d3-a318-a1501b17b654",
    "metadata": {},
    "outputs": [],
+   "source": [
+    "!g++ -c splitB.cpp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "18139a04-62f9-4b71-bb87-6a35fe4b87f6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!nm -C splitB.o"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "756fe777-5ac5-4ef7-84de-a9dc9a91b9c0",
+   "metadata": {},
+   "outputs": [],
    "source": []
   }
  ],
-- 
GitLab