diff --git a/notebooks/04_Classes+Objects.ipynb b/notebooks/04_Classes+Objects.ipynb index b12c155df25e717185c8f8be376b64e27e53a9e5..e6f23b376be17c47d3f926bb2f4ed745ef9c7060 100644 --- a/notebooks/04_Classes+Objects.ipynb +++ b/notebooks/04_Classes+Objects.ipynb @@ -1 +1,1929 @@ -{"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":"## Classes and Objects\n\nLet's try to implement our first class","metadata":{},"id":"e0e9c863-8720-40a4-a22c-00af773497fe"},{"cell_type":"code","source":"class aggregate {\n short s = 4;\n unsigned int i = 1u<<16;\n double x = 2.0;\n};","metadata":{"trusted":true},"execution_count":1,"outputs":[],"id":"bc685489-cf28-4a15-b0ee-fef2e6143f28"},{"cell_type":"code","source":"#include <iostream>\n\nint main() {\n aggregate agg;\n std::cout << \"s = \" << agg.s << std::endl;\n std::cout << \"i = \" << agg.i << std::endl;\n}","metadata":{"trusted":true},"execution_count":2,"outputs":[{"name":"stderr","text":"input_line_9:3:32: error: 's' is a private member of '__cling_N52::aggregate'\n std::cout << \"s = \" << agg.s << std::endl;\n ^\ninput_line_7:2:11: note: implicitly declared private here\n short s = 4;\n ^\ninput_line_9:4:32: error: 'i' is a private member of '__cling_N52::aggregate'\n std::cout << \"i = \" << agg.i << std::endl;\n ^\ninput_line_7:3:18: note: implicitly declared private here\n unsigned int i = 1u<<16;\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"4ada47eb-7158-4caf-aa60-0eb8df7e4769"},{"cell_type":"markdown","source":"That did not work. Why?","metadata":{},"id":"4035a6b6-f751-44fa-a579-a1166df4eed7"},{"cell_type":"markdown","source":"Because object-oriented programming is also about **encapsulation**. By making certain attributes (data members) and method (member functions) invisible to the outside, we\n - can enhance safety: better control over the state of an object\n - make sure that the internal implementation of the class can be changed without breaking outside code \n\nIn C++ we have three levels of access:\n - **public** = any one has access \n - **private** = only the class itself has access\n - **protected** = the class and its children have access\n \nThe difference between a struct and a class lies in their default setting\n\n| | class | struct |\n|:----------:|:-----:|:------:|\n| default is:|private| public |","metadata":{},"id":"159ef323-6f0a-49af-ac06-98804334e5d1"},{"cell_type":"code","source":"class aggregate {\n \n double x; // private by default\n \npublic:\n \n short s = 4;\n unsigned int i = 1u<<16;\n\n};\n\nstruct combo {\n \n int a; // public by default\n \nprivate:\n int internal; // not accessible from outside\n\n};","metadata":{"trusted":true},"execution_count":3,"outputs":[],"id":"7ea6dfba-43fe-4730-b845-4bd49c9b3e3a"},{"cell_type":"code","source":"#include <iostream>\n\nint main() {\n aggregate agg;\n std::cout << \"s = \" << agg.s << std::endl;\n std::cout << \"i = \" << agg.i << std::endl;\n\n combo s;\n s.a = 7;\n}\n\nmain();","metadata":{"trusted":true},"execution_count":4,"outputs":[{"name":"stderr","text":"In file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[5], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_12:3:13: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [5]]\n std::cout << \"s = \" << agg.s << std::endl;\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, const short &, void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_12:3:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = short]\n std::cout << \"s = \" << agg.s << std::endl;\n ^\ninput_line_12:3:35: error: reference to overloaded function could not be resolved; did you mean to call it?\n std::cout << \"s = \" << agg.s << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, const unsigned int &, void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_12:4:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = unsigned int]\n std::cout << \"i = \" << agg.i << std::endl;\n ^\ninput_line_12:4:23: error: use of overloaded operator '<<' is ambiguous (with operand types 'basic_ostream<char, std::char_traits<char> >' and 'unsigned int')\n std::cout << \"i = \" << agg.i << std::endl;\n ~~~~~~~~~~~~~~~~~~~ ^ ~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>]\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_12:3:13: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"s = \" << agg.s << std::endl;\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"6b4cd5c9-0ec3-451b-95b3-e9ad857eea83"},{"cell_type":"markdown","source":"An **object** is an instance of a class; different objects are different entities.","metadata":{},"id":"8c9241eb-1530-42db-8f50-542b8b74bbb8"},{"cell_type":"code","source":"int main() {\n \n aggregate a, b, c;\n \n a.s = 1;\n b.s = 2;\n c.s = 3;\n \n std::cout << \"a's short has a value of \" << a.s << '\\n'\n << \"b's short has a value of \" << b.s << '\\n'\n << \"c's short has a value of \" << c.s << std::endl;\n \n a = c;\n std::cout << \"now a.s = \" << a.s << std::endl;\n}","metadata":{"trusted":true},"execution_count":5,"outputs":[{"name":"stderr","text":"In file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[26], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_13:9:15: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [26]]\n std::cout << \"a's short has a value of \" << a.s << '\\n'\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, const char &, void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_13:9:53: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char]\n std::cout << \"a's short has a value of \" << a.s << '\\n'\n ^\ninput_line_13:11:56: error: reference to overloaded function could not be resolved; did you mean to call it?\n << \"c's short has a value of \" << c.s << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[11], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_13:14:15: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [11]]\n std::cout << \"now a.s = \" << a.s << std::endl;\n ^\ninput_line_13:14:41: error: reference to overloaded function could not be resolved; did you mean to call it?\n std::cout << \"now a.s = \" << a.s << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_5:1:\nIn file included from /srv/conda/envs/notebook/include/xeus/xinterpreter.hpp:17:\nIn file included from /srv/conda/envs/notebook/include/xeus/xcomm.hpp:19:\nIn file included from /srv/conda/envs/notebook/include/nlohmann/json.hpp:42:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/iterator:64:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_13:9:15: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"a's short has a value of \" << a.s << '\\n'\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"2f93bb55-528a-4bac-8336-ccf98cc18af0"},{"cell_type":"code","source":"main();","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"e5ca8f44-4f3f-4142-8b5e-f5a3c31fee7e"},{"cell_type":"markdown","source":"### Constructors\n\n- Our class *aggregate* used *default member initializers* for setting initial values for its data members.\n- This is one possibility. The other is to use a *constructor* and a *member initializer list*.\n- Constructors are also required, if we want to run some start-up code as part of object creation.","metadata":{},"id":"fe29c0f5-6967-403d-b796-779fe1ccf4be"},{"cell_type":"code","source":"#include <iostream>\n\nclass myClass{\n \n public:\n myClass() : memb_(0) {\n std::cout << \"An instance of myClass was generated.\"\n << \" memb_ = \" << memb_ << std::endl;\n }\n \n private:\n int memb_; // some people adhere to the convention of marking data members by a trailing \"_\"\n}","metadata":{"trusted":true},"execution_count":6,"outputs":[{"name":"stderr","text":"In file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[38], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_15:5:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [38]]\n std::cout << \"An instance of myClass was generated.\"\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[10], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_15:6:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [10]]\n << \" memb_ = \" << memb_ << std::endl;\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, const int &, void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_15:6:38: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = int]\n << \" memb_ = \" << memb_ << std::endl;\n ^\ninput_line_15:6:50: error: reference to overloaded function could not be resolved; did you mean to call it?\n << \" memb_ = \" << memb_ << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_5:1:\nIn file included from /srv/conda/envs/notebook/include/xeus/xinterpreter.hpp:17:\nIn file included from /srv/conda/envs/notebook/include/xeus/xcomm.hpp:19:\nIn file included from /srv/conda/envs/notebook/include/nlohmann/json.hpp:42:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/iterator:64:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_15:5:23: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"An instance of myClass was generated.\"\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"4c961b3c-ba83-46e6-aab1-08f1ad4102e3"},{"cell_type":"code","source":"int main() {\n myClass myObj;\n}\n\nmain();","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"f501dce2-ef23-4345-8072-45ea85cb8c17"},{"cell_type":"markdown","source":"#### Multiple Constructors\nC++ allows to overload functions. One can use this to implement different constructors.","metadata":{},"id":"5a5ded92-91fc-4a2f-8628-d9531cd84ea2"},{"cell_type":"code","source":"class myClass{\n \n public:\n myClass() : memb_(0) {\n std::cout << \"An instance of myClass was generated.\"\n << \" memb_ = \" << memb_ << std::endl;\n }\n \n myClass( int member ) : memb_(member) {\n std::cout << \"An instance of myClass was generated.\"\n << \" memb_ = \" << memb_ << std::endl;\n }\n \n private:\n int memb_;\n}","metadata":{"trusted":true},"execution_count":7,"outputs":[{"name":"stderr","text":"input_line_16:6:50: error: reference to overloaded function could not be resolved; did you mean to call it?\n << \" memb_ = \" << memb_ << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\ninput_line_16:11:50: error: reference to overloaded function could not be resolved; did you mean to call it?\n << \" memb_ = \" << memb_ << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_5:1:\nIn file included from /srv/conda/envs/notebook/include/xeus/xinterpreter.hpp:17:\nIn file included from /srv/conda/envs/notebook/include/xeus/xcomm.hpp:19:\nIn file included from /srv/conda/envs/notebook/include/nlohmann/json.hpp:42:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/iterator:64:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_16:5:23: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"An instance of myClass was generated.\"\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"3f4cf1f6-8c50-4057-ab71-259c1046222a"},{"cell_type":"code","source":"int main() {\n myClass myObj1;\n myClass myObj2( 5 );\n}\n\nmain();","metadata":{"trusted":true},"execution_count":8,"outputs":[{"name":"stderr","text":"input_line_17:2:5: error: unknown type name 'myClass'\n myClass myObj1;\n ^\ninput_line_17:3:5: error: unknown type name 'myClass'\n myClass myObj2( 5 );\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"51015ed7-9f4e-40c0-bfa9-2b9f98cd0e1e"},{"cell_type":"markdown","source":"#### Constructor Delegation","metadata":{},"id":"ee95a999-1b5a-4c1b-b2a3-d7dc9a6b306f"},{"cell_type":"markdown","source":"In the example above the body of both constructors is identical. Such a code duplication is, of course, not nice and in violation of the **D**on't **R**epeat **Y**ourself principle. We can avoid this by using **constructor delegation**.","metadata":{},"id":"b977d057-634f-4027-a177-6866bf88160b"},{"cell_type":"code","source":"#include <iostream>\n\nclass myClass{\n \n public:\n myClass( int member ) : memb_(member) {\n std::cout << \"An instance of myClass was generated.\"\n << \" memb_ = \" << memb_ << std::endl;\n }\n\n myClass() : myClass(0) {}\n \n private:\n int memb_;\n};","metadata":{"trusted":true},"execution_count":9,"outputs":[{"name":"stderr","text":"input_line_19:6:50: error: reference to overloaded function could not be resolved; did you mean to call it?\n << \" memb_ = \" << memb_ << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_5:1:\nIn file included from /srv/conda/envs/notebook/include/xeus/xinterpreter.hpp:17:\nIn file included from /srv/conda/envs/notebook/include/xeus/xcomm.hpp:19:\nIn file included from /srv/conda/envs/notebook/include/nlohmann/json.hpp:42:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/iterator:64:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_19:5:23: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"An instance of myClass was generated.\"\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"8eed6ec9-9ad6-48ab-b0e2-ab0ea35b9b57"},{"cell_type":"markdown","source":"#### Cleaning up: Destructors\nWhen an object goes out of scope and is destroyed we might want or need to do some housekeeping. For this we can implement a destructor.","metadata":{},"id":"fa5b47ea-8d12-4f55-8efe-c08588b81dbc"},{"cell_type":"code","source":"#include <iostream>\n\nclass VerboseClass{\n \n public:\n // c'tor\n VerboseClass() {\n std::cout << \"An instance of VerboseClass was generated.\" << std::endl;\n }\n\n // d'tor\n ~VerboseClass() {\n std::cout << \"An instance of VerboseClass was destroyed.\\n\" << std::endl;\n }\n};","metadata":{"trusted":true},"execution_count":10,"outputs":[{"name":"stderr","text":"input_line_21:6:74: error: reference to overloaded function could not be resolved; did you mean to call it?\n std::cout << \"An instance of VerboseClass was generated.\" << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[44], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_21:10:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [44]]\n std::cout << \"An instance of VerboseClass was destroyed.\\n\" << std::endl;\n ^\ninput_line_21:10:76: error: reference to overloaded function could not be resolved; did you mean to call it?\n std::cout << \"An instance of VerboseClass was destroyed.\\n\" << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\nIn file included from input_line_5:1:\nIn file included from /srv/conda/envs/notebook/include/xeus/xinterpreter.hpp:17:\nIn file included from /srv/conda/envs/notebook/include/xeus/xcomm.hpp:19:\nIn file included from /srv/conda/envs/notebook/include/nlohmann/json.hpp:42:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/iterator:64:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_21:6:23: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"An instance of VerboseClass was generated.\" << std::endl;\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"e456ce69-71e5-4169-b3e8-f302c3f72242"},{"cell_type":"code","source":"int main() {\n for( int k = 0; k < 3; k++ ) {\n VerboseClass talky;\n }\n}\n\nmain();","metadata":{"trusted":true},"execution_count":11,"outputs":[{"name":"stderr","text":"input_line_22:3:9: error: unknown type name 'VerboseClass'\n VerboseClass talky;\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"8fe56e9c-1842-4c29-84eb-1b20b3f7704a"},{"cell_type":"markdown","source":"#### Small Project: A Vector Class for Linear Algebra\nTasks:\n- We want to implement a class that represents a vector entity from linear algebra.\n- The size of the vector should be selectable at object creation -> need to allocate memory dynamically.\n- Access to vector entries should be 1-based -> operator overloading.\n- Implement simple methods, such as\n - scaling vector with a constant\n - adding two vectors together\n - compute the Euclidean inner product of two vectors","metadata":{},"id":"dffe4043-6959-4169-b0df-203a50d36e0f"},{"cell_type":"code","source":"// --------------------------------------\n// Start with the skeleton of the class\n// --------------------------------------\n\n#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n\n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n};","metadata":{"trusted":true},"execution_count":12,"outputs":[{"name":"stderr","text":"In file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[50], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_25:14:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [50]]\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n ^\ninput_line_25:14:78: error: use of overloaded operator '<<' is ambiguous (with operand types 'basic_ostream<char, std::char_traits<char> >' and 'unsigned int')\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>]\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:568:8: error: no member named 'setstate' in 'std::basic_ostream<char>'\n __out.setstate(ios_base::badbit);\n ~~~~~ ^\ninput_line_25:14:23: note: in instantiation of function template specialization 'std::operator<<<std::char_traits<char> >' requested here\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"f33e5eef-b396-4bfc-8031-f21b33839611"},{"cell_type":"code","source":"int main() {\n VectorClass myVec( 10 );\n}","metadata":{"trusted":true},"execution_count":13,"outputs":[{"name":"stderr","text":"input_line_26:2:5: error: unknown type name 'VectorClass'\n VectorClass myVec( 10 );\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"e2f2ac16-a0df-4f6c-816a-cb47420f4989"},{"cell_type":"code","source":"main();","metadata":{"trusted":true},"execution_count":14,"outputs":[{"name":"stderr","text":"input_line_27:2:2: error: use of undeclared identifier 'main'\n main();\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"7c06f924-8412-449c-a5b5-a56b1df2ff2b"},{"cell_type":"markdown","source":"Our implementation is **missing an essential piece**? What could that be?","metadata":{},"id":"935b6f8d-d347-4edb-9807-f2ed3563dcaf"},{"cell_type":"code","source":"// --------------------------------------\n// Start with the skeleton of the class\n// --------------------------------------\n\n#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n \n // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n // memory leaks\n ~VectorClass() {\n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n};","metadata":{"trusted":true},"execution_count":null,"outputs":[{"name":"stderr","text":"input_line_30:14:78: error: use of overloaded operator '<<' is ambiguous (with operand types 'basic_ostream<char, std::char_traits<char> >' and 'unsigned int')\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>]\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function [with _Traits = std::char_traits<char>]\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[46], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_30:23:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [46]]\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n ^\nIn file included from input_line_1:1:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/new:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/exception:144:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/nested_exception.h:40:\nIn file included from /srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/move.h:55:\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/type_traits:137:31: error: no member named 'value' in 'std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >'\n : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type\n ~~~~~^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:685:24: note: in instantiation of template class 'std::__and_<std::__not_<std::is_lvalue_reference<std::basic_ostream<char> &> >, std::__is_convertible_to_basic_ostream<std::basic_ostream<char> &>, std::__is_insertable<std::basic_ostream<char> &, char const (&)[14], void> >' requested here\n typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>,\n ^\ninput_line_30:24:23: note: while substituting deduced template arguments into function template 'operator<<' [with _Ostream = std::basic_ostream<char> &, _Tp = char [14]]\n << \" bytes freed.\" << std::endl;\n ^\ninput_line_30:24:45: error: reference to overloaded function could not be resolved; did you mean to call it?\n << \" bytes freed.\" << std::endl;\n ^~~~~~~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:599:5: note: possible target for call\n endl(basic_ostream<_CharT, _Traits>& __os)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no overload of 'endl' matching 'const void *' for 1st argument\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/string_view:580:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'basic_string_view<char, std::char_traits<char> >' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no overload of 'endl' matching 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no overload of 'endl' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no overload of 'endl' matching 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no overload of 'endl' matching 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no overload of 'endl' matching 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no overload of 'endl' matching 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no overload of 'endl' matching 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no overload of 'endl' matching 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no overload of 'endl' matching 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no overload of 'endl' matching 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no overload of 'endl' matching 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:250:7: note: candidate function not viable: no overload of 'endl' matching 'std::nullptr_t' (aka 'nullptr_t') for 1st argument\n operator<<(nullptr_t)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no overload of 'endl' matching 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no overload of 'endl' matching 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no overload of 'endl' matching 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no overload of 'endl' matching 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>] not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no overload of 'endl' matching 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no overload of 'endl' matching 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no overload of 'endl' matching 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: couldn't infer template argument '_Alloc'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/cstddef:130:5: note: candidate template ignored: couldn't infer template argument '_IntegerType'\n operator<<(byte __b, _IntegerType __shift) noexcept\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: couldn't infer template argument '_Tp'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: couldn't infer template argument '_Dom'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: couldn't infer template argument '_Tp'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413","output_type":"stream"}],"id":"102897af-957e-43b7-a959-eb6ee468f35d"},{"cell_type":"code","source":"int main() {\n VectorClass myVec( 10 );\n}\n\nmain();","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"adcac578-0bca-4aed-8d13-4514826dd0e7"},{"cell_type":"markdown","source":"Our VectorClass is currently 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- add a getter method for the dimension\n- add a member function to pretty-print the vector's entries","metadata":{},"id":"1a74105b-5453-49ab-aeed-e0371809fc52"},{"cell_type":"code","source":"#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n \n // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n // memory leaks\n ~VectorClass() {\n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // provide access to the vector's dimension\n unsigned int getDim() { return dim_; }\n \n // overload the [] for accessing individual entries\n double& operator[] ( unsigned int index ){\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n // pretty print vector to given output stream\n void print( std::ostream &os ) {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"a32eb08a-822a-4b83-b3d0-6de281acffba"},{"cell_type":"code","source":"// Let's test our extended class\n\nint main() {\n \n VectorClass myVec( 3 );\n \n myVec[ 1 ] = 3.0;\n myVec[ 2 ] = 2.0;\n myVec[ 3 ] = 1.0;\n \n myVec.print( std::cout );\n}\n\nmain();","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"4eb50e73-21f5-4669-9464-32f11d958732"},{"cell_type":"markdown","source":"**What is left on our todo-list?**\nImplement simple methods, such as\n - scaling vector with a constant\n - adding two vectors together\n - compute the Euclidean inner product of two vectors","metadata":{},"id":"d8af8c97-2855-41f9-bda2-9d5ae341b7c0"},{"cell_type":"code","source":"%%file VectorClass.cpp\n\n#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n \n // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n // memory leaks\n ~VectorClass() {\n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // provide access to the vector's dimension\n unsigned int getDim() { return dim_; }\n \n // overload the [] for accessing individual entries\n double& operator[] ( unsigned int index ){\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n // pretty print vector to given output stream (default will be std::cout)\n void print( std::ostream &os = std::cout ) {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n // scale vector with a constant\n void scale( double factor ) {\n // leave that to students\n }\n \n // add to vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n // for the moment leave it with adding another vector to the one on which the method is called.\n \n // let us try the following, and determine, why it will fail ;-)\n void add( VectorClass other ) {\n\n // 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 }\n //for( unsigned int k = 1; k <= dim_; k++ ) {\n // this->operator[](k) += other[k];\n //}\n }\n \n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};\n\n// Modify driver a little bit\nint 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 second( dim );\n for( unsigned int idx = 1; idx <= dim; idx ++ ) {\n second[ idx ] = static_cast<double>( idx );\n }\n second.print( std::cout );\n \n // add the 2nd to the 1st\n myVec.add( second );\n myVec.print();\n}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"cdfde2f9-fafc-4a9f-99b7-4952720e4521"},{"cell_type":"code","source":"!g++ -g VectorClass.cpp","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"f9331dc3-19ff-44a2-a8f5-6e258f9266d2"},{"cell_type":"code","source":"!./a.out","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"4f4d196d-761d-40e1-9d08-5df87307476b"},{"cell_type":"markdown","source":"**Note**: The adding itself seems to have worked correctly, but somehow we still have a problem. So what's wrong here?","metadata":{},"id":"3e04234e-4f33-44c4-9adb-0bde893019df"},{"cell_type":"markdown","source":"The answer to this is multifaceted:\n- Our implementation of *add()* used **call-by-copy**\n- Since we pass an object, its **copy constructor** is invoked\n- We haven't implemented one, but the compiler did automatically (thank's for that ;-)\n- Thus, the copy we get of **other** is a **flat** one!","metadata":{},"id":"7551ddc3-e449-47f1-bdc8-9a8080acdaf9"},{"cell_type":"markdown","source":"***\nWe can check on that by making the destructor tell us which block it is going to deallocate and run our code through valgrind:\n***\n**==> valgrind ./a.out**\n<div>\n==28488== Memcheck, a memory error detector</br>\n==28488== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.</br>\n==28488== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info</br>\n==28488== Command: ./a.out</br>\n==28488== </br>\nAn instance of VectorClass was generated. dim_ = 10</br>\n(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)</br>\nAn instance of VectorClass was generated. dim_ = 10</br>\n(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)</br>\n<font color=\"red\">Going to delete memory starting at address 0x4d9b150</font></br>\nAn instance of VectorClass was destroyed and 80 bytes freed.</br>\n(11, 11, 11, 11, 11, 11, 11, 11, 11, 11)</br>\n<font color=\"red\">Going to delete memory starting at address 0x4d9b150</font></br>\n==28488== Invalid free() / delete / delete[] / realloc()</br>\n==28488== at 0x483758B: operator delete[](void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)</br>\n==28488== by 0x109500: VectorClass::~VectorClass() (VectorClass3.cpp:30)</br>\n==28488== by 0x109341: main (VectorClass3.cpp:93)</br>\n==28488== Address 0x4d9b150 is 0 bytes inside a block of size 80 free'd</br>\n==28488== at 0x483758B: operator delete[](void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)</br>\n==28488== by 0x109500: VectorClass::~VectorClass() (VectorClass3.cpp:30)</br>\n==28488== by 0x109322: main (VectorClass3.cpp:100)</br>\n==28488== Block was alloc'd at</br>\n==28488== at 0x483650F: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)</br>\n==28488== by 0x109450: VectorClass::VectorClass(unsigned int) (VectorClass3.cpp:15)</br>\n==28488== by 0x109291: main (VectorClass3.cpp:93)</br>\n==28488== </br>\nAn instance of VectorClass was destroyed and 80 bytes freed.</br>\nGoing to delete memory starting at address 0x4d9ac80</br>\nAn instance of VectorClass was destroyed and 80 bytes freed.</br>\n==28488== </br>\n==28488== HEAP SUMMARY:</br>\n==28488== in use at exit: 0 bytes in 0 blocks</br>\n==28488== total heap usage: 4 allocs, 5 frees, 73,888 bytes allocated</br>\n==28488== </br>\n==28488== All heap blocks were freed -- no leaks are possible</br>\n==28488== </br>\n==28488== For counts of detected and suppressed errors, rerun with: -v</br>\n==28488== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)</br>\n</div>","metadata":{},"id":"02714f7e-52c4-4890-8a87-05ca91d651e5"},{"cell_type":"markdown","source":"Another way to check on this is to remove the automatic copy constructor","metadata":{},"id":"48d75c49-dd79-420e-9e00-c75865245b5c"},{"cell_type":"code","source":"%%file VectorClass.cpp\n\n#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n\n // Don't allow the following default copy constructor either\n VectorClass( VectorClass &other ) = delete;\n \n // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n // memory leaks\n ~VectorClass() {\n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // provide access to the vector's dimension\n unsigned int getDim() { return dim_; }\n \n // overload the [] for accessing individual entries\n double& operator[] ( unsigned int index ){\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n // pretty print vector to given output stream (default will be std::cout)\n void print( std::ostream &os = std::cout ) {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n // scale vector with a constant\n void scale( double factor ) {\n // leave that to students\n }\n \n // add to vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n // for the moment leave it with adding another vector to the one on which the method is called.\n \n // let us try the following, and determine, why it will fail ;-)\n void add( VectorClass other ) {\n\n // 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 // }\n for( unsigned int k = 1; k <= dim_; k++ ) {\n this->operator[](k) += other[k];\n }\n }\n \n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};\n\n// Modify driver a little bit\nint 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}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"def80c0f-89b6-4e00-995a-14b8e800975c"},{"cell_type":"code","source":"!g++ VectorClass.cpp","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"473de9eb-b04c-4087-8444-8d4b3c4c9fb8"},{"cell_type":"markdown","source":"#### Solution?\nHow should we resolve the issue?\n***\nFor the current case the best solution is to change the interface of our `add()` method to be\n\n`void add( const VectorClass& other )`\n\nThe `const` is no must, but makes it clear to other programmers and the compiler that we are not going to change the object\nother inside add().","metadata":{},"id":"91724843-2e97-4862-888a-291fda71444a"},{"cell_type":"code","source":"#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n\n // Don't allow the following default copy constructor either\n VectorClass( VectorClass &other ) = delete;\n \n // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n // memory leaks\n ~VectorClass() {\n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // provide access to the vector's dimension\n unsigned int getDim() { return dim_; }\n \n // overload the [] for accessing individual entries\n double& operator[] ( unsigned int index ){\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n // pretty print vector to given output stream (default will be std::cout)\n void print( std::ostream &os = std::cout ) {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n // scale vector with a constant\n void scale( double factor ) {\n // leave that to students\n }\n \n // add to vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n // for the moment leave it with adding another vector to the one on which the method is called.\n \n // let us try the following, and determine, why it will fail ;-)\n void add( const VectorClass& other ) {\n\n // 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 // }\n for( unsigned int k = 1; k <= dim_; k++ ) {\n this->operator[](k) += other[k];\n }\n }\n \n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};\n\n// Modify driver a little bit\nint 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}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"30eccd22-8c5e-4062-a1d1-8006981aae99"},{"cell_type":"markdown","source":"***\nAh, okay. So the `const` was a good idea, but requires a little bit of extra work!\n\nWe need to implement a second version of the operator overloading that returns a const reference!","metadata":{},"id":"a6bfec6d-9eba-4e34-9ec8-e74bfa485664"},{"cell_type":"code","source":"#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \n public:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n\n // Don't allow the following default copy constructor either\n VectorClass( VectorClass &other ) = delete;\n \n // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n // memory leaks\n ~VectorClass() {\n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // provide access to the vector's dimension\n unsigned int getDim() { return dim_; }\n \n // overload the [] for accessing individual entries\n double& operator[] ( unsigned int index ){\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n \n // overload the [] for accessing individual entries\n const double& operator[] ( unsigned int index ) {\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n \n // pretty print vector to given output stream (default will be std::cout)\n void print( std::ostream &os = std::cout ) {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n // scale vector with a constant\n void scale( double factor ) {\n // leave that to students\n }\n \n // add to vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n // for the moment leave it with adding another vector to the one on which the method is called.\n \n // let us try the following, and determine, why it will fail ;-)\n void add( const VectorClass& other ) {\n\n // 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 // }\n for( unsigned int k = 1; k <= dim_; k++ ) {\n this->operator[](k) += other[k];\n }\n }\n \n private:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};\n\n// Modify driver a little bit\nint 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}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"15b02a70-a496-4098-a446-9a60ee30b116"},{"cell_type":"markdown","source":"Shoot, we have a problem with the **signature** now!\n\nBut, fortunately, there is a way out of this:\n- We can tell the compiler that a member function does not alter its object! This will also be part of the signature. So we can implement our overloading as\n`const double& operator[] ( unsigned int index ) const`\n- We might want to do this also for any other member function that does not change the object, like e.g. `print()`\n\nIf we do this, we end up with the final version:","metadata":{},"id":"6a78d290-77dc-43a5-93f5-15fa2c650ddb"},{"cell_type":"code","source":"#include <iostream>\n#include <cassert>\n\nclass VectorClass {\n \npublic:\n \n // User should specify dimension at object creation\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" \n << dim_ << std::endl;\n }\n\n // Don't allow the default constructor\n // [prior to C++11 you would solve this by making it private]\n VectorClass() = delete;\n\n // Don't allow the following default copy constructor either \n VectorClass( VectorClass &other ) = delete;\n \n // We need to implement a destructor to free the dynamic memory again,\n // otherwise we easily produce memory leaks\n ~VectorClass() {\n std::cout << \"Going to delete memory starting at address \"\n << vec_ << std::endl;\n \n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \"\n << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // provide access to the vector's dimension\n unsigned int getDim() const { return dim_; }\n \n // overload the [] for accessing individual entries\n double& operator[] ( unsigned int index ) {\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n const double& operator[] ( unsigned int index ) const {\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n // pretty print vector to given output stream (default will be std::cout)\n void print( std::ostream &os = std::cout ) const {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n // scale vector with a constant\n void scale( double factor ) {\n // leave that to students\n }\n \n // add to vectors together (that's actually a little bit tricky,\n // due to the question \"where to put the result?\"\n // for the moment leave it with adding another vector to the one on which\n // the method is called.\n void add( const VectorClass& other ) {\n\n // 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 // }\n for( unsigned int k = 1; k <= dim_; k++ ) {\n this->operator[](k) += other[k];\n }\n }\n \nprivate:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"0b2a852d-2a07-4f2a-85d2-7833051474d7"},{"cell_type":"code","source":"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}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"81aeb13c-be8f-4e15-b7d7-acffb4a575eb"},{"cell_type":"code","source":"main();","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"77177a38-424a-4558-8836-9c6f95bdd7c0"},{"cell_type":"markdown","source":"***\n#### Separating Implementation and Interface\n\n- Assume that we have the definition of a `class A` in one source file and want to use the class in another source file `B.cpp`.\n- For this the compiler needs to known at least that `class A` exists: \n This can be accomplished by a **forward declaration** of the form `class A;`\n- However, if we also want to access data or function members of A, the compiler needs further info.\n- There are three possibilities:\n 1. Put the complete definition of A into a header file `A.hpp` and include that into the source file `B.cpp`\n 1. Split up the declaration of the member functions and their implementation into two parts. A file `A.hpp` with the class declaration and a file `A.cpp` with the implementation of the member functions.\n 1. Use a combination of both, e.g. to allow inlining of certain short methods.\n- Each of the approaches has pros and cons. So the decision depends on the concrete scenario.\n***\nBrief example on the splitting approach:","metadata":{},"id":"56fb8027-e846-451f-bcda-c28c6e805530"},{"cell_type":"code","source":"%%file splitA.hpp\n\n#include <string>\n\nclass A {\n\n std::string name_;\n\n public:\n void setName( const char* name );\n void printName();\n\n};","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"867de208-5492-44c0-bf04-7ac9f868908f"},{"cell_type":"code","source":"%%file splitA.cpp\n\n// Necessary, because otherwise compiler does not know a class A and a member function setName exists\n#include \"splitA.hpp\"\n\n// Need to prefix the member function name with the class name\nvoid A::setName( const char* name ) {\n name_ = name;\n}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"639efb26-6150-4cdf-aef4-b962ba86a6a3"},{"cell_type":"code","source":"%%file splitB.cpp\n\n#include \"splitA.hpp\"\n\nint main( void ) {\n\n A obj;\n obj.setName( \"An object\" );\n\n // Note: We have not implemented A::printName();\n // However, if it is not used, that's not an issue.\n // obj.printName();\n}","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"3ed47b3b-3b45-4fc3-ab31-655915b41251"},{"cell_type":"code","source":"!g++ splitA.cpp splitB.cpp\n./a.out","metadata":{"trusted":true},"execution_count":null,"outputs":[],"id":"2c897fb0-b3a2-4617-8b92-79dbaaff6b8b"},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[],"id":"782da53e-ca04-42d3-a318-a1501b17b654"}]} \ No newline at end of file +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e0e9c863-8720-40a4-a22c-00af773497fe", + "metadata": {}, + "source": [ + "## Classes and Objects\n", + "\n", + "Let's try to implement our first class" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "bc685489-cf28-4a15-b0ee-fef2e6143f28", + "metadata": {}, + "outputs": [], + "source": [ + "class aggregate {\n", + " short s = 4;\n", + " unsigned int i = 1u<<16;\n", + " double x = 2.0;\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4ada47eb-7158-4caf-aa60-0eb8df7e4769", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[1minput_line_9:3:32: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m's' is a private member of '__cling_N52::aggregate'\u001b[0m\n", + " std::cout << \"s = \" << agg.s << std::endl;\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1minput_line_7:2:11: \u001b[0m\u001b[0;1;30mnote: \u001b[0mimplicitly declared private here\u001b[0m\n", + " short s = 4;\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1minput_line_9:4:32: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1m'i' is a private member of '__cling_N52::aggregate'\u001b[0m\n", + " std::cout << \"i = \" << agg.i << std::endl;\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1minput_line_7:3:18: \u001b[0m\u001b[0;1;30mnote: \u001b[0mimplicitly declared private here\u001b[0m\n", + " unsigned int i = 1u<<16;\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m" + ] + }, + { + "ename": "Interpreter Error", + "evalue": "", + "output_type": "error", + "traceback": [ + "Interpreter Error: " + ] + } + ], + "source": [ + "#include <iostream>\n", + "\n", + "int main() {\n", + " aggregate agg;\n", + " std::cout << \"s = \" << agg.s << std::endl;\n", + " std::cout << \"i = \" << agg.i << std::endl;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "4035a6b6-f751-44fa-a579-a1166df4eed7", + "metadata": {}, + "source": [ + "That did not work. Why?" + ] + }, + { + "cell_type": "markdown", + "id": "159ef323-6f0a-49af-ac06-98804334e5d1", + "metadata": {}, + "source": [ + "Because object-oriented programming is also about **encapsulation**. By making certain attributes (data members) and methods (member functions) invisible to the outside, we\n", + " - can enhance safety: better control over the state of an object\n", + " - make sure that the internal implementation of the class can be changed without breaking outside code \n", + "\n", + "In C++ we have three levels of access:\n", + " - **public** = any one has access \n", + " - **private** = only the class itself has access\n", + " - **protected** = the class and its children have access\n", + " \n", + "The difference between a struct and a class lies in their default setting\n", + "\n", + "| | class | struct |\n", + "|:----------:|:-----:|:------:|\n", + "| default is:|private| public |" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7ea6dfba-43fe-4730-b845-4bd49c9b3e3a", + "metadata": {}, + "outputs": [], + "source": [ + "class aggregate {\n", + " \n", + " double x; // private by default\n", + " \n", + "public:\n", + " \n", + " short s = 4;\n", + " unsigned int i = 1u<<16;\n", + "\n", + "};\n", + "\n", + "struct combo {\n", + " \n", + " int a; // public by default\n", + " \n", + "private:\n", + " int internal; // not accessible from outside\n", + "\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6b4cd5c9-0ec3-451b-95b3-e9ad857eea83", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "s = 4\n", + "i = 65536\n" + ] + } + ], + "source": [ + "#include <iostream>\n", + "\n", + "int main() {\n", + " aggregate agg;\n", + " std::cout << \"s = \" << agg.s << std::endl;\n", + " std::cout << \"i = \" << agg.i << std::endl;\n", + "\n", + " combo s;\n", + " s.a = 7;\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "8c9241eb-1530-42db-8f50-542b8b74bbb8", + "metadata": {}, + "source": [ + "An **object** is an instance of a class; different objects are different entities." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2f93bb55-528a-4bac-8336-ccf98cc18af0", + "metadata": {}, + "outputs": [], + "source": [ + "int main() {\n", + " \n", + " aggregate a, b, c;\n", + " \n", + " a.s = 1;\n", + " b.s = 2;\n", + " c.s = 3;\n", + " \n", + " std::cout << \"a's short has a value of \" << a.s << '\\n'\n", + " << \"b's short has a value of \" << b.s << '\\n'\n", + " << \"c's short has a value of \" << c.s << std::endl;\n", + " \n", + " a = c;\n", + " std::cout << \"now a.s = \" << a.s << std::endl;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "e5ca8f44-4f3f-4142-8b5e-f5a3c31fee7e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a's short has a value of 1\n", + "b's short has a value of 2\n", + "c's short has a value of 3\n", + "now a.s = 3\n" + ] + } + ], + "source": [ + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "fe29c0f5-6967-403d-b796-779fe1ccf4be", + "metadata": {}, + "source": [ + "### Constructors\n", + "\n", + "- Our class *aggregate* used *default member initializers* for setting initial values for its data members.\n", + "- This is one possibility. The other is to use a *constructor* and a *member initializer list*.\n", + "- Constructors are also required, if we want to run some start-up code as part of object creation." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4c961b3c-ba83-46e6-aab1-08f1ad4102e3", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "\n", + "class myClass{\n", + " \n", + " public:\n", + " myClass() : memb_(0) {\n", + " std::cout << \"An instance of myClass was generated.\"\n", + " << \" memb_ = \" << memb_ << std::endl;\n", + " }\n", + " \n", + " private:\n", + " int memb_; // some people adhere to the convention of marking data members by a trailing \"_\"\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f501dce2-ef23-4345-8072-45ea85cb8c17", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of myClass was generated. memb_ = 0\n" + ] + } + ], + "source": [ + "int main() {\n", + " myClass myObj;\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "5a5ded92-91fc-4a2f-8628-d9531cd84ea2", + "metadata": {}, + "source": [ + "#### Multiple Constructors\n", + "C++ allows to overload functions. One can use this to implement different constructors." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3f4cf1f6-8c50-4057-ab71-259c1046222a", + "metadata": {}, + "outputs": [], + "source": [ + "class myClass{\n", + " \n", + " public:\n", + " myClass() : memb_(0) {\n", + " std::cout << \"An instance of myClass was generated.\"\n", + " << \" memb_ = \" << memb_ << std::endl;\n", + " }\n", + " \n", + " myClass( int member ) : memb_(member) {\n", + " std::cout << \"An instance of myClass was generated.\"\n", + " << \" memb_ = \" << memb_ << std::endl;\n", + " }\n", + " \n", + " private:\n", + " int memb_;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "51015ed7-9f4e-40c0-bfa9-2b9f98cd0e1e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of myClass was generated. memb_ = 0\n", + "An instance of myClass was generated. memb_ = 5\n" + ] + } + ], + "source": [ + "int main() {\n", + " myClass myObj1;\n", + " myClass myObj2( 5 );\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "ee95a999-1b5a-4c1b-b2a3-d7dc9a6b306f", + "metadata": {}, + "source": [ + "#### Constructor Delegation" + ] + }, + { + "cell_type": "markdown", + "id": "b977d057-634f-4027-a177-6866bf88160b", + "metadata": {}, + "source": [ + "In the example above the body of both constructors is identical. Such a code duplication is, of course, not nice and in violation of the **D**on't **R**epeat **Y**ourself principle. We can avoid this by using **constructor delegation**." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "8eed6ec9-9ad6-48ab-b0e2-ab0ea35b9b57", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "\n", + "class myClass{\n", + " \n", + " public:\n", + " myClass( int member ) : memb_(member) {\n", + " std::cout << \"An instance of myClass was generated.\"\n", + " << \" memb_ = \" << memb_ << std::endl;\n", + " }\n", + "\n", + " myClass() : myClass(0) {}\n", + " \n", + " private:\n", + " int memb_;\n", + "};" + ] + }, + { + "cell_type": "markdown", + "id": "fa5b47ea-8d12-4f55-8efe-c08588b81dbc", + "metadata": {}, + "source": [ + "#### Cleaning up: Destructors\n", + "When an object goes out of scope and is destroyed we might want or need to do some housekeeping. For this we can implement a destructor." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e456ce69-71e5-4169-b3e8-f302c3f72242", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "\n", + "class VerboseClass{\n", + " \n", + " public:\n", + " // c'tor\n", + " VerboseClass() {\n", + " std::cout << \"An instance of VerboseClass was generated.\" << std::endl;\n", + " }\n", + "\n", + " // d'tor\n", + " ~VerboseClass() {\n", + " std::cout << \"An instance of VerboseClass was destroyed.\\n\" << std::endl;\n", + " }\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "8fe56e9c-1842-4c29-84eb-1b20b3f7704a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VerboseClass was generated.\n", + "An instance of VerboseClass was destroyed.\n", + "\n", + "An instance of VerboseClass was generated.\n", + "An instance of VerboseClass was destroyed.\n", + "\n", + "An instance of VerboseClass was generated.\n", + "An instance of VerboseClass was destroyed.\n", + "\n" + ] + } + ], + "source": [ + "int main() {\n", + " for( int k = 0; k < 3; k++ ) {\n", + " VerboseClass talky;\n", + " }\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "dffe4043-6959-4169-b0df-203a50d36e0f", + "metadata": {}, + "source": [ + "#### Small Project: A Vector Class for Linear Algebra\n", + "Tasks:\n", + "- We want to implement a class that represents a vector entity from linear algebra.\n", + "- The size of the vector should be selectable at object creation -> need to allocate memory dynamically.\n", + "- Access to vector entries should be 1-based -> operator overloading.\n", + "- Implement simple methods, such as\n", + " - scaling vector with a constant\n", + " - adding two vectors together\n", + " - compute the Euclidean inner product of two vectors" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "f33e5eef-b396-4bfc-8031-f21b33839611", + "metadata": {}, + "outputs": [], + "source": [ + "// --------------------------------------\n", + "// Start with the skeleton of the class\n", + "// --------------------------------------\n", + "\n", + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( !dim_ == 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \"\n", + " << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would have solved this by making it private]\n", + " VectorClass() = delete;\n", + "\n", + " private:\n", + " unsigned int dim_; // dimension of vector\n", + " double* vec_; // entries of vector\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e2f2ac16-a0df-4f6c-816a-cb47420f4989", + "metadata": {}, + "outputs": [], + "source": [ + "int main() {\n", + " VectorClass myVec( 420 );\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "7c06f924-8412-449c-a5b5-a56b1df2ff2b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VectorClass was generated. dim_ = 420\n" + ] + } + ], + "source": [ + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "935b6f8d-d347-4edb-9807-f2ed3563dcaf", + "metadata": {}, + "source": [ + "Our implementation is **missing an essential piece**? What could that be?" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "102897af-957e-43b7-a959-eb6ee468f35d", + "metadata": {}, + "outputs": [], + "source": [ + "// --------------------------------------\n", + "// Start with the skeleton of the class\n", + "// --------------------------------------\n", + "\n", + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \"\n", + " << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would have solved this by making it private]\n", + " VectorClass() = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " ~VectorClass() {\n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " private:\n", + " unsigned int dim_; // dimension of vector\n", + " double* vec_; // entries of vector\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "adcac578-0bca-4aed-8d13-4514826dd0e7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VectorClass was generated. dim_ = 10\n", + "An instance of VectorClass was destroyed and 80 bytes freed.\n" + ] + } + ], + "source": [ + "int main() {\n", + " VectorClass myVec( 10 );\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "1a74105b-5453-49ab-aeed-e0371809fc52", + "metadata": {}, + "source": [ + "Our VectorClass is currently 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", + "- add a getter method for the dimension\n", + "- add a member function to pretty-print the vector's entries" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "a32eb08a-822a-4b83-b3d0-6de281acffba", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \"\n", + " << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would have solved this by making it private]\n", + " VectorClass() = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " ~VectorClass() {\n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // provide access to the vector's dimension\n", + " unsigned int getDim() { return dim_; }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " double& operator[] ( unsigned int index ) {\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " // pretty print vector to given output stream\n", + " void print( std::ostream& os ) {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " private:\n", + " unsigned int dim_; // dimension of vector\n", + " double* vec_; // entries of vector\n", + "\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "4eb50e73-21f5-4669-9464-32f11d958732", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VectorClass was generated. dim_ = 3\n", + "Our vector has dimension 3 and entries: (3, 2, 1)\n", + "An instance of VectorClass was destroyed and 24 bytes freed.\n" + ] + } + ], + "source": [ + "// Let's test our extended class\n", + "\n", + "int main() {\n", + " \n", + " VectorClass myVec( 3 );\n", + " \n", + " myVec[ 1 ] = 3.0;\n", + " myVec[ 2 ] = 2.0;\n", + " myVec[ 3 ] = 1.0;\n", + " \n", + " std::cout << \"Our vector has dimension \" << myVec.getDim()\n", + " << \" and entries: \";\n", + " myVec.print( std::cout );\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "d8af8c97-2855-41f9-bda2-9d5ae341b7c0", + "metadata": {}, + "source": [ + "**What is left on our todo-list?**\n", + "Implement simple methods, such as\n", + " - scaling vector with a constant\n", + " - adding two vectors together\n", + " - compute the Euclidean inner product of two vectors" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "cdfde2f9-fafc-4a9f-99b7-4952720e4521", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting VectorClass.cpp\n" + ] + } + ], + "source": [ + "%%file VectorClass.cpp\n", + "\n", + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \"\n", + " << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would have solved this by making it private]\n", + " VectorClass() = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " ~VectorClass() {\n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // provide access to the vector's dimension\n", + " unsigned int getDim() { return dim_; }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " double& operator[] ( unsigned int index ){\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " // pretty print vector to given output stream (default will be std::cout)\n", + " void print( std::ostream &os = std::cout ) {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " // scale vector with a constant\n", + " void scale( double factor ) {\n", + " // leave that to students\n", + " }\n", + " \n", + " // add two vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n", + " // for the moment leave it with adding another vector to the one on which the method is called;\n", + " // let us try the following, and determine, why it will fail ;-)\n", + " void add( VectorClass other ) {\n", + "\n", + " // 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", + " }\n", + " //for( unsigned int k = 1; k <= dim_; k++ ) {\n", + " // this->operator[](k) += other[k];\n", + " //}\n", + " }\n", + " \n", + " private:\n", + " 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 + 1u );\n", + " }\n", + " myVec.print( std::cout );\n", + " \n", + " // set up 2nd vector\n", + " VectorClass second( dim );\n", + " for( unsigned int idx = 1; idx <= dim; idx ++ ) {\n", + " second[ idx ] = static_cast<double>( idx );\n", + " }\n", + " second.print( std::cout );\n", + " \n", + " // add the 2nd to the 1st\n", + " myVec.add( second );\n", + " myVec.print();\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "f9331dc3-19ff-44a2-a8f5-6e258f9266d2", + "metadata": {}, + "outputs": [], + "source": [ + "!g++ -g VectorClass.cpp" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "4f4d196d-761d-40e1-9d08-5df87307476b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VectorClass was generated. dim_ = 10\n", + "(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n", + "An instance of VectorClass was generated. dim_ = 10\n", + "(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n", + "An instance of VectorClass was destroyed and 80 bytes freed.\n", + "(11, 11, 11, 11, 11, 11, 11, 11, 11, 11)\n", + "free(): double free detected in tcache 2\n", + "Aborted (core dumped)\n" + ] + } + ], + "source": [ + "!./a.out" + ] + }, + { + "cell_type": "markdown", + "id": "3e04234e-4f33-44c4-9adb-0bde893019df", + "metadata": {}, + "source": [ + "**Note**: The adding itself seems to have worked correctly, but somehow we still have a problem. So what's wrong here?" + ] + }, + { + "cell_type": "markdown", + "id": "7551ddc3-e449-47f1-bdc8-9a8080acdaf9", + "metadata": {}, + "source": [ + "The answer to this is multifaceted:\n", + "- Our implementation of *add()* used **call-by-copy**\n", + "- Since we pass an object, its **copy constructor** is invoked\n", + "- We haven't implemented one, but the compiler did automatically (thank's for that ;-)\n", + "- Thus, the copy we get of **other** is a **flat** one!" + ] + }, + { + "cell_type": "markdown", + "id": "02714f7e-52c4-4890-8a87-05ca91d651e5", + "metadata": {}, + "source": [ + "***\n", + "We can check on that by making the destructor tell us which block it is going to deallocate and run our code through valgrind:\n", + "***\n", + "**==> valgrind ./a.out**\n", + "<div>\n", + "==28488== Memcheck, a memory error detector</br>\n", + "==28488== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.</br>\n", + "==28488== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info</br>\n", + "==28488== Command: ./a.out</br>\n", + "==28488== </br>\n", + "An instance of VectorClass was generated. dim_ = 10</br>\n", + "(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)</br>\n", + "An instance of VectorClass was generated. dim_ = 10</br>\n", + "(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)</br>\n", + "<font color=\"red\">Going to delete memory starting at address 0x4d9b150</font></br>\n", + "An instance of VectorClass was destroyed and 80 bytes freed.</br>\n", + "(11, 11, 11, 11, 11, 11, 11, 11, 11, 11)</br>\n", + "<font color=\"red\">Going to delete memory starting at address 0x4d9b150</font></br>\n", + "==28488== Invalid free() / delete / delete[] / realloc()</br>\n", + "==28488== at 0x483758B: operator delete[](void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)</br>\n", + "==28488== by 0x109500: VectorClass::~VectorClass() (VectorClass3.cpp:30)</br>\n", + "==28488== by 0x109341: main (VectorClass3.cpp:93)</br>\n", + "==28488== Address 0x4d9b150 is 0 bytes inside a block of size 80 free'd</br>\n", + "==28488== at 0x483758B: operator delete[](void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)</br>\n", + "==28488== by 0x109500: VectorClass::~VectorClass() (VectorClass3.cpp:30)</br>\n", + "==28488== by 0x109322: main (VectorClass3.cpp:100)</br>\n", + "==28488== Block was alloc'd at</br>\n", + "==28488== at 0x483650F: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)</br>\n", + "==28488== by 0x109450: VectorClass::VectorClass(unsigned int) (VectorClass3.cpp:15)</br>\n", + "==28488== by 0x109291: main (VectorClass3.cpp:93)</br>\n", + "==28488== </br>\n", + "An instance of VectorClass was destroyed and 80 bytes freed.</br>\n", + "Going to delete memory starting at address 0x4d9ac80</br>\n", + "An instance of VectorClass was destroyed and 80 bytes freed.</br>\n", + "==28488== </br>\n", + "==28488== HEAP SUMMARY:</br>\n", + "==28488== in use at exit: 0 bytes in 0 blocks</br>\n", + "==28488== total heap usage: 4 allocs, 5 frees, 73,888 bytes allocated</br>\n", + "==28488== </br>\n", + "==28488== All heap blocks were freed -- no leaks are possible</br>\n", + "==28488== </br>\n", + "==28488== For counts of detected and suppressed errors, rerun with: -v</br>\n", + "==28488== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)</br>\n", + "</div>" + ] + }, + { + "cell_type": "markdown", + "id": "48d75c49-dd79-420e-9e00-c75865245b5c", + "metadata": {}, + "source": [ + "Another way to check on this is to remove the automatic copy constructor" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "def80c0f-89b6-4e00-995a-14b8e800975c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting VectorClass.cpp\n" + ] + } + ], + "source": [ + "%%file VectorClass.cpp\n", + "\n", + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would solve this by making it private]\n", + " VectorClass() = delete;\n", + "\n", + " // Don't allow the following default copy constructor either\n", + " VectorClass( VectorClass &other ) = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " ~VectorClass() {\n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // provide access to the vector's dimension\n", + " unsigned int getDim() { return dim_; }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " double& operator[] ( unsigned int index ){\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " // pretty print vector to given output stream (default will be std::cout)\n", + " void print( std::ostream &os = std::cout ) {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " // scale vector with a constant\n", + " void scale( double factor ) {\n", + " // leave that to students\n", + " }\n", + " \n", + " // add two vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n", + " // for the moment leave it with adding another vector to the one on which the method is called;\n", + " // let us try the following, and determine, why it will fail ;-)\n", + " void add( VectorClass other ) {\n", + "\n", + " // 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", + " // }\n", + " for( unsigned int k = 1; k <= dim_; k++ ) {\n", + " this->operator[](k) += other[k];\n", + " }\n", + " }\n", + " \n", + " private:\n", + " 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", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "473de9eb-b04c-4087-8444-8d4b3c4c9fb8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "VectorClass.cpp: In function ‘int main()’:\n", + "VectorClass.cpp:102:22: error: use of deleted function ‘VectorClass::VectorClass(VectorClass&)’\n", + " myVec.add( other );\n", + " ^\n", + "VectorClass.cpp:27:9: note: declared here\n", + " VectorClass( VectorClass &other ) = delete;\n", + " ^~~~~~~~~~~\n", + "VectorClass.cpp:64:14: note: initializing argument 1 of ‘void VectorClass::add(VectorClass)’\n", + " void add( VectorClass other ) {\n", + " ^~~\n" + ] + } + ], + "source": [ + "!g++ VectorClass.cpp" + ] + }, + { + "cell_type": "markdown", + "id": "91724843-2e97-4862-888a-291fda71444a", + "metadata": {}, + "source": [ + "#### Solution?\n", + "How should we resolve the issue?\n", + "***\n", + "For the current case the best solution is to change the interface of our `add()` method to be\n", + "\n", + "`void add( const VectorClass& other )`\n", + "\n", + "The `const` is no must, but makes it clear to other programmers and the compiler that we are not going to change the object\n", + "other inside add()." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "30eccd22-8c5e-4062-a1d1-8006981aae99", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[1minput_line_8: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_8: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_8: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" + ] + }, + { + "ename": "Interpreter Error", + "evalue": "", + "output_type": "error", + "traceback": [ + "Interpreter Error: " + ] + } + ], + "source": [ + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor [prior to C++11 you would solve this by making it private]\n", + " VectorClass() = delete;\n", + "\n", + " // Don't allow the following default copy constructor either\n", + " VectorClass( VectorClass &other ) = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again, otherwise we easily produce\n", + " // memory leaks\n", + " ~VectorClass() {\n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \" << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // provide access to the vector's dimension\n", + " unsigned int getDim() { return dim_; }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " double& operator[] ( unsigned int index ){\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " // pretty print vector to given output stream (default will be std::cout)\n", + " void print( std::ostream &os = std::cout ) {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " // scale vector with a constant\n", + " void scale( double factor ) {\n", + " // leave that to students\n", + " }\n", + " \n", + " // add two vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n", + " // for the moment leave it with adding another vector to the one on which the method is called.\n", + " \n", + " // let us try the following, and determine, why it will fail ;-)\n", + " void add( const VectorClass& other ) {\n", + "\n", + " // 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", + " // }\n", + " for( unsigned int k = 1; k <= dim_; k++ ) {\n", + " this->operator[](k) += other[k];\n", + " }\n", + " }\n", + " \n", + " private:\n", + " 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", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "a6bfec6d-9eba-4e34-9ec8-e74bfa485664", + "metadata": {}, + "source": [ + "***\n", + "Ah, okay. So the `const` was a good idea, but requires a little bit of extra work!\n", + "\n", + "We need to implement a second version of the operator overloading that returns a const reference!" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "15b02a70-a496-4098-a446-9a60ee30b116", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[1minput_line_10: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_10: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_10:15:23: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types\n", + " '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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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_10:28:23: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types\n", + " '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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[0m\u001b[1minput_line_10:50:20: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types 'std::ostream'\n", + " (aka 'basic_ostream<char>') and 'double')\u001b[0m\n", + " os << vec_[k] << \", \";\n", + "\u001b[0;1;32m ~~ ^ ~~~~~~~\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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_10:52:16: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1muse of overloaded operator '<<' is ambiguous (with operand types 'std::ostream'\n", + " (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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.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_10: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_10:35:17: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: 'this' argument has type 'const VectorClass', but\n", + " method is not marked const\u001b[0m\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + " double& operator[] ( unsigned int index ){\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1minput_line_10: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/mohr/local/miniconda3/envs/cling/include/xeus/xinterpreter.hpp:17:\n", + "In file included from /home/mohr/local/miniconda3/envs/cling/include/xeus/xcomm.hpp:19:\n", + "In file included from /home/mohr/local/miniconda3/envs/cling/include/nlohmann/json.hpp:42:\n", + "In file included from /home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/iterator:64:\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:568: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_10:14:23: \u001b[0m\u001b[0;1;30mnote: \u001b[0min instantiation of function template specialization\n", + " '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" + ] + }, + { + "ename": "Interpreter Error", + "evalue": "", + "output_type": "error", + "traceback": [ + "Interpreter Error: " + ] + } + ], + "source": [ + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + " public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \"\n", + " << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would solve this by making it private]\n", + " VectorClass() = delete;\n", + "\n", + " // Don't allow the following default copy constructor either\n", + " VectorClass( VectorClass &other ) = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " ~VectorClass() {\n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // provide access to the vector's dimension\n", + " unsigned int getDim() { return dim_; }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " double& operator[] ( unsigned int index ){\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " const double& operator[] ( unsigned int index ) {\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + " \n", + " // pretty print vector to given output stream (default will be std::cout)\n", + " void print( std::ostream &os = std::cout ) {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " // scale vector with a constant\n", + " void scale( double factor ) {\n", + " // leave that to students\n", + " }\n", + " \n", + " // add to vectors together (that's actually a little bit tricky, due to the question \"where to put the result?\"\n", + " // for the moment leave it with adding another vector to the one on which the method is called;\n", + " // let us try the following, and determine, why it will fail ;-)\n", + " void add( const VectorClass& other ) {\n", + "\n", + " // 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", + " // }\n", + " for( unsigned int k = 1; k <= dim_; k++ ) {\n", + " this->operator[](k) += other[k];\n", + " }\n", + " }\n", + " \n", + " private:\n", + " 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", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "6a78d290-77dc-43a5-93f5-15fa2c650ddb", + "metadata": {}, + "source": [ + "Shoot, we have a problem with the **signature** now!\n", + "\n", + "But, fortunately, there is a way out of this:\n", + "- We can tell the compiler that a member function does not alter its object! This will also be part of the signature. So we can implement our overloading as\n", + "`const double& operator[] ( unsigned int index ) const`\n", + "- We might want to do this also for any other member function that does not change the object, like e.g. `print()`\n", + "\n", + "Additionally, let us make add() nicer by using the fact that objects of the same class have access to their private data members!\n", + "\n", + "If we do both, we end up with the final version:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0b2a852d-2a07-4f2a-85d2-7833051474d7", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass {\n", + " \n", + "public:\n", + " \n", + " // User should specify dimension at object creation\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \" \n", + " << dim_ << std::endl;\n", + " }\n", + "\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would solve this by making it private]\n", + " VectorClass() = delete;\n", + "\n", + " // Don't allow the following default copy constructor either \n", + " VectorClass( VectorClass &other ) = delete;\n", + " \n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " ~VectorClass() {\n", + " std::cout << \"Going to delete memory starting at address \"\n", + " << vec_ << std::endl;\n", + " \n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // provide access to the vector's dimension\n", + " unsigned int getDim() const { return dim_; }\n", + " \n", + " // overload the [] for accessing individual entries\n", + " double& operator[] ( unsigned int index ) {\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " const double& operator[] ( unsigned int index ) const {\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " // pretty print vector to given output stream (default will be std::cout)\n", + " void print( std::ostream &os = std::cout ) const {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " // scale vector with a constant\n", + " void scale( double factor ) {\n", + " // leave that to students\n", + " }\n", + " \n", + " // add to vectors together (that's actually a little bit tricky,\n", + " // due to the question \"where to put the result?\";\n", + " // for the moment leave it with adding another vector to the one on which\n", + " // the method is called.\n", + " void add( const VectorClass& other ) {\n", + "\n", + " // make sure that input vector has correct length\n", + " assert( other.dim_ == dim_ );\n", + " for( unsigned int k = 0; k < dim_; k++ ) {\n", + " vec_[k] += other.vec_[k];\n", + " }\n", + " }\n", + " \n", + "private:\n", + " unsigned int dim_; // dimension of vector\n", + " double* vec_; // entries of vector\n", + "\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "81aeb13c-be8f-4e15-b7d7-acffb4a575eb", + "metadata": {}, + "outputs": [], + "source": [ + "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", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "77177a38-424a-4558-8836-9c6f95bdd7c0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VectorClass was generated. dim_ = 10\n", + "(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n", + "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 0x561e481ef440\n", + "An instance of VectorClass was destroyed and 80 bytes freed.\n", + "Going to delete memory starting at address 0x561e480f55f0\n", + "An instance of VectorClass was destroyed and 80 bytes freed.\n" + ] + } + ], + "source": [ + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "56fb8027-e846-451f-bcda-c28c6e805530", + "metadata": {}, + "source": [ + "***\n", + "#### Separating Implementation and Interface\n", + "\n", + "- Assume that we have the definition of a `class A` in one source file and want to use the class in another source file `B.cpp`.\n", + "- For this the compiler needs to known at least that `class A` exists: \n", + " This can be accomplished by a **forward declaration** of the form `class A;`\n", + "- However, if we also want to access data or function members of A, the compiler needs further info.\n", + "- There are three possibilities:\n", + " 1. Put the complete definition of A into a header file `A.hpp` and include that into the source file `B.cpp`\n", + " 1. Split up the declaration of the member functions and their implementation into two parts. A file `A.hpp` with the class declaration and a file `A.cpp` with the implementation of the member functions.\n", + " 1. Use a combination of both, e.g. to allow inlining of certain short methods.\n", + "- Each of the approaches has pros and cons. So the decision depends on the concrete scenario.\n", + "***\n", + "Brief example on the splitting approach:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "867de208-5492-44c0-bf04-7ac9f868908f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting splitA.hpp\n" + ] + } + ], + "source": [ + "%%file splitA.hpp\n", + "\n", + "#include <string>\n", + "\n", + "class A {\n", + "\n", + " std::string name_;\n", + "\n", + " public:\n", + " void setName( const char* name );\n", + " void printName();\n", + "\n", + "};" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "639efb26-6150-4cdf-aef4-b962ba86a6a3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting splitA.cpp\n" + ] + } + ], + "source": [ + "%%file splitA.cpp\n", + "\n", + "// Necessary, because otherwise compiler does not know a class A and a member function setName exists\n", + "#include \"splitA.hpp\"\n", + "\n", + "// Need to prefix the member function name with the class name\n", + "void A::setName( const char* name ) {\n", + " name_ = name;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "3ed47b3b-3b45-4fc3-ab31-655915b41251", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting splitB.cpp\n" + ] + } + ], + "source": [ + "%%file splitB.cpp\n", + "\n", + "#include \"splitA.hpp\"\n", + "\n", + "int main( void ) {\n", + "\n", + " A obj;\n", + " obj.setName( \"An object\" );\n", + "\n", + " // Note: We have not implemented A::printName();\n", + " // However, if it is not used, that's not an issue.\n", + " // obj.printName();\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "2c897fb0-b3a2-4617-8b92-79dbaaff6b8b", + "metadata": {}, + "outputs": [], + "source": [ + "!g++ splitA.cpp splitB.cpp\n", + "./a.out" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "782da53e-ca04-42d3-a318-a1501b17b654", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "C++14", + "language": "C++14", + "name": "xcpp14" + }, + "language_info": { + "codemirror_mode": "text/x-c++src", + "file_extension": ".cpp", + "mimetype": "text/x-c++src", + "name": "c++", + "version": "14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/05_Friendship.ipynb b/notebooks/05_Friendship.ipynb index bfae721a174df54a4f0d83105a93d847a1aecfc2..1c4b94cddbd5026244f527ae6ef4dc7943acc8f0 100644 --- a/notebooks/05_Friendship.ipynb +++ b/notebooks/05_Friendship.ipynb @@ -1 +1,475 @@ -{"metadata":{"orig_nbformat":4,"language_info":{"codemirror_mode":"text/x-c++src","file_extension":".cpp","mimetype":"text/x-c++src","name":"c++","version":"11"},"kernelspec":{"name":"xcpp11","display_name":"C++11","language":"C++11"}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Friendship","metadata":{},"id":"e04e0b83-753f-4a58-bce3-3746e7c69650"},{"cell_type":"markdown","source":"* In many situations we tend to make the data members of our classes **private** (or protected in the case of inheritance). \n* If we do so, then no objects of other classes or free-functions have access to them. Not even other objects of the same class.\n* Sometimes this is too restrictive, though. We might need to provide direct access to our members for selected **friends**.\n\n* A typical example is, when we want to overload the ```<<``` operator, to be able to place our object into an output stream.","metadata":{},"id":"6c224ee8-f4c0-495c-8261-6d2c17f845a6"},{"cell_type":"markdown","source":"***\nLet us create a simpe demo class","metadata":{},"id":"ff1a3263-e349-4840-af2f-ad90fde352ac"},{"cell_type":"code","source":"class myTuple {\n\n int fir;\n int sec;\n\npublic:\n myTuple( int fir, int sec ) : fir(fir), sec(sec) {};\n\n};","metadata":{"trusted":true},"execution_count":1,"outputs":[],"id":"cebe299d-3bcc-4a57-af69-8aed41401244"},{"cell_type":"markdown","source":"and try to test-run it","metadata":{},"id":"97622c4c-2eba-47cd-8dbb-c2fe9963dbc3"},{"cell_type":"code","source":"#include <iostream>\n\nint main() {\n\n myTuple obj( 3, 5 );\n\n std::cout << \"Pair is: \" << obj << std::endl;\n}\n\nmain();","metadata":{"trusted":true},"execution_count":2,"outputs":[{"name":"stderr","text":"input_line_9:3:28: error: invalid operands to binary expression ('basic_ostream<char, std::char_traits<char> >' and '__cling_N52::myTuple')\n std::cout << \"Pair is: \" << obj << std::endl;\n ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:245:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'const void *' for 1st argument; take the address of the argument with &\n operator<<(const void* __p)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/system_error:217:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'const std::error_code' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:108:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'std::basic_ostream<char, std::char_traits<char> >::__ostream_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &)' (aka 'basic_ostream<char, std::char_traits<char> > &(*)(basic_ostream<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ostream_type& (*__pf)(__ostream_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:117:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n operator<<(__ios_type& (*__pf)(__ios_type&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:127:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n operator<<(ios_base& (*__pf) (ios_base&))\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:166:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'long' for 1st argument\n operator<<(long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:170:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'unsigned long' for 1st argument\n operator<<(unsigned long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:174:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'bool' for 1st argument\n operator<<(bool __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:178:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'short' for 1st argument\n operator<<(short __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:181:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'unsigned short' for 1st argument\n operator<<(unsigned short __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:189:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'int' for 1st argument\n operator<<(int __n);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:192:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'unsigned int' for 1st argument\n operator<<(unsigned int __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:201:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'long long' for 1st argument\n operator<<(long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:205:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'unsigned long long' for 1st argument\n operator<<(unsigned long long __n)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:220:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'double' for 1st argument\n operator<<(double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:224:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'float' for 1st argument\n operator<<(float __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:232:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'long double' for 1st argument\n operator<<(long double __f)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:276:7: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n operator<<(__streambuf_type* __sb);\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:511:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'char' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:517:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:523:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'signed char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:528:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'unsigned char' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:565:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'const char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:578:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'const signed char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:583:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'const unsigned char *' for 2nd argument\n operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/ostream.tcc:321:5: note: candidate function not viable: no known conversion from '__cling_N52::myTuple' to 'const char *' for 2nd argument\n operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:506:5: note: candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. '__cling_N52::myTuple')\n operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/basic_string.h:6419:5: note: candidate template ignored: could not match 'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>' against '__cling_N52::myTuple'\n operator<<(basic_ostream<_CharT, _Traits>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:548:5: note: candidate template ignored: could not match 'const _CharT *' against '__cling_N52::myTuple'\n operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/ostream:691:5: note: candidate template ignored: requirement '__and_<__not_<is_lvalue_reference<basic_ostream<char> &> >, __is_convertible_to_basic_ostream<basic_ostream<char> &>, __is_insertable<__rvalue_ostream_type<basic_ostream<char> &>, const myTuple &> >::value' was not satisfied [with _Ostream = std::basic_ostream<char> &, _Tp = __cling_N52::myTuple]\n operator<<(_Ostream&& __os, const _Tp& __x)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/shared_ptr.h:66:5: note: candidate template ignored: could not match '__shared_ptr<type-parameter-0-2, _Lp>' against '__cling_N52::myTuple'\n operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:344:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:357:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr<type-parameter-0-0, typename type-parameter-0-0::value_type>' against '__cling_N52::myTuple'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:370:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const typename _Dom::value_type& __t, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:383:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:413:5: note: candidate template ignored: could not match '_Expr<type-parameter-0-0, typename type-parameter-0-0::value_type>' against '__cling_N52::myTuple'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/bits/valarray_after.h:396:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1166:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const valarray<_Tp>& __v, \\\n ^\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1193:1: note: candidate template ignored: could not match 'valarray<type-parameter-0-0>' against '__cling_N52::myTuple'\n/srv/conda/envs/notebook/bin/../lib/gcc/../../x86_64-conda-linux-gnu/include/c++/9.4.0/valarray:1177:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n ^\n","output_type":"stream"},{"ename":"Interpreter Error","evalue":"","traceback":["Interpreter Error: "],"output_type":"error"}],"id":"7b80f338-bd48-4699-81aa-fbae245a3a04"},{"cell_type":"markdown","source":"Okay that obviously did not work. Problem is that ```<<``` does not know how to work with objects of type ```myTuple```.\n\n\n* We can fix this by implementing a version of ```<<``` that understands it. \n* Different from our overloading of ```[ ]``` for our ```VectorClass```, we do not do this on the object. Instead we need to overload the free-function that is ```<<```.","metadata":{},"id":"8b28c2a6-533e-478b-91e1-b63270121d6c"},{"cell_type":"code","source":"%%file myTuple.cpp\n\n#include <iostream>\n\nclass myTuple {\n\n int fir;\n int sec;\n\npublic:\n myTuple( int fir, int sec ) : fir(fir), sec(sec) {};\n\n};\n\nstd::ostream& operator << ( std::ostream &os, const myTuple& tup )\n{\n os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\";\n \n // necessary for chaining:\n return os;\n}","metadata":{"trusted":true},"execution_count":3,"outputs":[{"name":"stdout","text":"Writing myTuple.cpp\n","output_type":"stream"}],"id":"8dfa7a1c-28d8-4de1-ae19-bdb2a6d3e48e"},{"cell_type":"code","source":"!g++ -Wall -Wextra -c myTuple.cpp","metadata":{"trusted":true},"execution_count":4,"outputs":[{"name":"stdout","text":"myTuple.cpp: In function ‘std::ostream& operator<<(std::ostream&, const myTuple&)’:\nmyTuple.cpp:16:23: error: ‘int myTuple::fir’ is private within this context\n os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\";\n ^~~\nmyTuple.cpp:6:7: note: declared private here\n int fir;\n ^~~\nmyTuple.cpp:16:43: error: ‘int myTuple::sec’ is private within this context\n os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\";\n ^~~\nmyTuple.cpp:7:7: note: declared private here\n int sec;\n ^~~\n","output_type":"stream"}],"id":"25e56a5e-6c64-4d77-9a81-5d808f2b63b3"},{"cell_type":"markdown","source":"* That was to be expected. The attributes ```fir``` and ```sec``` of ```myTuple``` are private.\n* However, we do not want to make them accessible to everyone, just for the sake of one special function/operator.\n* But, we can do so **selectively**, with the friend statement.","metadata":{},"id":"092b284c-9b78-4ea9-9b9a-f43cc5f32612"},{"cell_type":"code","source":"%%file myTuple.cpp\n\n#include <iostream>\n\nclass myTuple {\n\n int fir;\n int sec;\n\n friend std::ostream& operator << ( std::ostream&, const myTuple& );\n\npublic:\n myTuple( int fir, int sec ) : fir(fir), sec(sec) {};\n\n};\n\nstd::ostream& operator << ( std::ostream &os, const myTuple& tup )\n{\n os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\" << std::endl;\n \n // necessary for chaining:\n return os;\n}\n\nint main() {\n\n myTuple obj( 3, 5 );\n\n std::cout << \"Pair is: \" << obj << std::endl;\n}","metadata":{"trusted":true},"execution_count":5,"outputs":[{"name":"stdout","text":"Overwriting myTuple.cpp\n","output_type":"stream"}],"id":"ff341d41-7aa2-4f87-92f2-e189dd448d68"},{"cell_type":"code","source":"!g++ -Wall -Wextra myTuple.cpp","metadata":{"trusted":true},"execution_count":6,"outputs":[],"id":"c8560f81-10ef-4203-b3f3-8046255be25a"},{"cell_type":"code","source":"!./a.out","metadata":{"trusted":true},"execution_count":7,"outputs":[{"name":"stdout","text":"Pair is: ( 3 , 5 )\n\n","output_type":"stream"}],"id":"6a5f1cb3-7891-4cb8-b8ce-d3f6aa996ecc"},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[],"id":"94e6f340-7a06-4c59-8889-5088e41712f2"}]} \ No newline at end of file +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e04e0b83-753f-4a58-bce3-3746e7c69650", + "metadata": {}, + "source": [ + "### Friendship" + ] + }, + { + "cell_type": "markdown", + "id": "6c224ee8-f4c0-495c-8261-6d2c17f845a6", + "metadata": {}, + "source": [ + "* In many situations we tend to make the data members of our classes **private** (or protected in the case of inheritance). \n", + "* If we do so, then no objects of other classes or free-functions have access to them. *(But other objects of the same class have.)*\n", + "* Sometimes this is too restrictive, though. We might need to provide direct access to our members for selected **friends**.\n", + "\n", + "* A typical example is, when we want to overload the ```<<``` operator, to be able to place our object into an output stream." + ] + }, + { + "cell_type": "markdown", + "id": "ff1a3263-e349-4840-af2f-ad90fde352ac", + "metadata": {}, + "source": [ + "***\n", + "Let us create a simpe demo class" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "cebe299d-3bcc-4a57-af69-8aed41401244", + "metadata": {}, + "outputs": [], + "source": [ + "class myTuple {\n", + "\n", + " int fir;\n", + " int sec;\n", + "\n", + "public:\n", + " myTuple( int fir, int sec ) : fir(fir), sec(sec) {};\n", + "\n", + "};" + ] + }, + { + "cell_type": "markdown", + "id": "97622c4c-2eba-47cd-8dbb-c2fe9963dbc3", + "metadata": {}, + "source": [ + "and try to test-run it" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "7b80f338-bd48-4699-81aa-fbae245a3a04", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[1minput_line_9:3:28: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1minvalid operands to binary expression ('basic_ostream<char,\n", + " std::char_traits<char> >' and '__cling_N52::myTuple')\u001b[0m\n", + " std::cout << \"Pair is: \" << obj << std::endl;\n", + "\u001b[0;1;32m ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:245:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'const void *' for 1st argument; take the address of the argument with\n", + " &\u001b[0m\n", + " operator<<(const void* __p)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/system_error:217:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'const std::error_code' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:108:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'std::basic_ostream<char, std::char_traits<char> >::__ostream_type\n", + " &(*)(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &)'\n", + " (aka 'basic_ostream<char, std::char_traits<char> >\n", + " &(*)(basic_ostream<char, std::char_traits<char> > &)') for 1st argument\u001b[0m\n", + " operator<<(__ostream_type& (*__pf)(__ostream_type&))\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:117:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'std::basic_ostream<char, std::char_traits<char> >::__ios_type\n", + " &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)'\n", + " (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char,\n", + " std::char_traits<char> > &)') for 1st argument\u001b[0m\n", + " operator<<(__ios_type& (*__pf)(__ios_type&))\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:127:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'std::ios_base &(*)(std::ios_base &)' for 1st argument\u001b[0m\n", + " operator<<(ios_base& (*__pf) (ios_base&))\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:166:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'long' for 1st argument\u001b[0m\n", + " operator<<(long __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:170:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'unsigned long' for 1st argument\u001b[0m\n", + " operator<<(unsigned long __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:174:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'bool' for 1st argument\u001b[0m\n", + " operator<<(bool __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:178:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'short' for 1st argument\u001b[0m\n", + " operator<<(short __n);\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:181:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'unsigned short' for 1st argument\u001b[0m\n", + " operator<<(unsigned short __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:189:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'int' for 1st argument\u001b[0m\n", + " operator<<(int __n);\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:192:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'unsigned int' for 1st argument\u001b[0m\n", + " operator<<(unsigned int __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:201:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'long long' for 1st argument\u001b[0m\n", + " operator<<(long long __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:205:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'unsigned long long' for 1st argument\u001b[0m\n", + " operator<<(unsigned long long __n)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:220:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'double' for 1st argument\u001b[0m\n", + " operator<<(double __f)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:224:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'float' for 1st argument\u001b[0m\n", + " operator<<(float __f)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:232:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'long double' for 1st argument\u001b[0m\n", + " operator<<(long double __f)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:276:7: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *'\n", + " (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\u001b[0m\n", + " operator<<(__streambuf_type* __sb);\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:511:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'char' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:517:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'char' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<char, _Traits>& __out, char __c)\n", + "\u001b[0;1;32m ^\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:523:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'signed char' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:528:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'unsigned char' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:565:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'const char *' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:578:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'const signed char *' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:583:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'const unsigned char *' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/ostream.tcc:321:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate function not viable: no known conversion from '__cling_N52::myTuple'\n", + " to 'const char *' for 2nd argument\u001b[0m\n", + " operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:506:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: deduced conflicting types for parameter '_CharT'\n", + " ('char' vs. '__cling_N52::myTuple')\u001b[0m\n", + " operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/basic_string.h:6416:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match 'basic_string<type-parameter-0-0,\n", + " type-parameter-0-1, type-parameter-0-2>' against '__cling_N52::myTuple'\u001b[0m\n", + " operator<<(basic_ostream<_CharT, _Traits>& __os,\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:548:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match 'const _CharT *' against\n", + " '__cling_N52::myTuple'\u001b[0m\n", + " operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/ostream:691:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: requirement\n", + " '__and_<__not_<is_lvalue_reference<basic_ostream<char> &> >,\n", + " __is_convertible_to_basic_ostream<basic_ostream<char> &>,\n", + " __is_insertable<__rvalue_ostream_type<basic_ostream<char> &>, const\n", + " myTuple &> >::value' was not satisfied [with _Ostream =\n", + " std::basic_ostream<char> &, _Tp = __cling_N52::myTuple]\u001b[0m\n", + " operator<<(_Ostream&& __os, const _Tp& __x)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/shared_ptr.h:66:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match '__shared_ptr<type-parameter-0-2,\n", + " _Lp>' against '__cling_N52::myTuple'\u001b[0m\n", + " operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:413:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match '_Expr' against 'basic_ostream'\u001b[0m\n", + " _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:344:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:413:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match '_Expr' against 'basic_ostream'\u001b[0m\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:357:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:413:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match '_Expr<type-parameter-0-0, typename\n", + " type-parameter-0-0::value_type>' against '__cling_N52::myTuple'\u001b[0m\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:370:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const typename _Dom::value_type& __t, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:413:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match '_Expr' against 'basic_ostream'\u001b[0m\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:383:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:413:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match '_Expr<type-parameter-0-0, typename\n", + " type-parameter-0-0::value_type>' against '__cling_N52::myTuple'\u001b[0m\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/bits/valarray_after.h:396:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const valarray<typename _Dom::value_type>& __v, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/valarray:1193:1: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match 'valarray' against 'basic_ostream'\u001b[0m\n", + "_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n", + "\u001b[0;1;32m^\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/valarray:1155:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/valarray:1193:1: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match 'valarray' against 'basic_ostream'\u001b[0m\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/valarray:1166:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const valarray<_Tp>& __v, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/valarray:1193:1: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcandidate template ignored: could not match 'valarray<type-parameter-0-0>'\n", + " against '__cling_N52::myTuple'\u001b[0m\n", + "\u001b[1m/home/mohr/local/miniconda3/envs/cling/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/include/c++/9.3.0/valarray:1177:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0mexpanded from macro '_DEFINE_BINARY_OPERATOR'\u001b[0m\n", + " operator _Op(const typename valarray<_Tp>::value_type& __t, \\\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m" + ] + }, + { + "ename": "Interpreter Error", + "evalue": "", + "output_type": "error", + "traceback": [ + "Interpreter Error: " + ] + } + ], + "source": [ + "#include <iostream>\n", + "\n", + "int main() {\n", + "\n", + " myTuple obj( 3, 5 );\n", + "\n", + " std::cout << \"Pair is: \" << obj << std::endl;\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "8b28c2a6-533e-478b-91e1-b63270121d6c", + "metadata": {}, + "source": [ + "Okay that obviously did not work. Problem is that ```<<``` does not know how to work with objects of type ```myTuple```.\n", + "\n", + "\n", + "* We can fix this by implementing a version of ```<<``` that understands it. \n", + "* Different from our overloading of ```[ ]``` for our ```VectorClass```, we do not do this on the object. Instead we need to overload the free-function that is ```<<```." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8dfa7a1c-28d8-4de1-ae19-bdb2a6d3e48e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting myTuple.cpp\n" + ] + } + ], + "source": [ + "%%file myTuple.cpp\n", + "\n", + "#include <iostream>\n", + "\n", + "class myTuple {\n", + "\n", + " int fir;\n", + " int sec;\n", + "\n", + "public:\n", + " myTuple( int fir, int sec ) : fir(fir), sec(sec) {};\n", + "\n", + "};\n", + "\n", + "std::ostream& operator << ( std::ostream &os, const myTuple& tup )\n", + "{\n", + " os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\";\n", + " \n", + " // necessary for chaining:\n", + " return os;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "25e56a5e-6c64-4d77-9a81-5d808f2b63b3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "myTuple.cpp: In function ‘std::ostream& operator<<(std::ostream&, const myTuple&)’:\n", + "myTuple.cpp:16:23: error: ‘int myTuple::fir’ is private within this context\n", + " os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\";\n", + " ^~~\n", + "myTuple.cpp:6:7: note: declared private here\n", + " int fir;\n", + " ^~~\n", + "myTuple.cpp:16:43: error: ‘int myTuple::sec’ is private within this context\n", + " os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\";\n", + " ^~~\n", + "myTuple.cpp:7:7: note: declared private here\n", + " int sec;\n", + " ^~~\n" + ] + } + ], + "source": [ + "!g++ -Wall -Wextra -c myTuple.cpp" + ] + }, + { + "cell_type": "markdown", + "id": "092b284c-9b78-4ea9-9b9a-f43cc5f32612", + "metadata": {}, + "source": [ + "* That was to be expected. The attributes ```fir``` and ```sec``` of ```myTuple``` are private.\n", + "* However, we do not want to make them accessible to everyone, just for the sake of one special function/operator.\n", + "* But, we can do so **selectively**, with the friend statement." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ff341d41-7aa2-4f87-92f2-e189dd448d68", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting myTuple.cpp\n" + ] + } + ], + "source": [ + "%%file myTuple.cpp\n", + "\n", + "#include <iostream>\n", + "\n", + "class myTuple {\n", + "\n", + " int fir;\n", + " int sec;\n", + "\n", + " friend std::ostream& operator << ( std::ostream&, const myTuple& );\n", + "\n", + "public:\n", + " myTuple( int fir, int sec ) : fir(fir), sec(sec) {};\n", + "\n", + "};\n", + "\n", + "std::ostream& operator << ( std::ostream &os, const myTuple& tup )\n", + "{\n", + " os << \"( \" << tup.fir << \" , \" << tup.sec << \" )\" << std::endl;\n", + " \n", + " // necessary for chaining:\n", + " return os;\n", + "}\n", + "\n", + "int main() {\n", + "\n", + " myTuple obj( 3, 5 );\n", + "\n", + " std::cout << \"Pair is: \" << obj << std::endl;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "c8560f81-10ef-4203-b3f3-8046255be25a", + "metadata": {}, + "outputs": [], + "source": [ + "!g++ -Wall -Wextra myTuple.cpp" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6a5f1cb3-7891-4cb8-b8ce-d3f6aa996ecc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pair is: ( 3 , 5 )\n", + "\n" + ] + } + ], + "source": [ + "!./a.out" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94e6f340-7a06-4c59-8889-5088e41712f2", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "C++11", + "language": "C++11", + "name": "xcpp11" + }, + "language_info": { + "codemirror_mode": "text/x-c++src", + "file_extension": ".cpp", + "mimetype": "text/x-c++src", + "name": "c++", + "version": "11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/Task#1.ipynb b/notebooks/Task#1.ipynb index 362373347f9e6d828c95dbbc55a87fda1e49c358..278c9df860ff61554ad24fe9620358fd99f0b55e 100644 --- a/notebooks/Task#1.ipynb +++ b/notebooks/Task#1.ipynb @@ -1 +1,485 @@ -{"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":"### Task #1\n\nIn this task we want to further extend our ```VectorClass``` class. Specifically we would like add two methods and answer a question concerning ```VectorClass::print()```: \n 1. Implement missing body of VectorClass::scale()\n 1. Implement VectorClass::innerProduct(), how should the header look like?\n 1. What happens, when we call myVec.print() without arguments in main?","metadata":{},"id":"5b54f8c4-59a0-4a5a-a15c-021d20ae3d22"},{"cell_type":"markdown","source":"Let us start with (2). How should the interface for ```innerProduct()``` look like?","metadata":{},"id":"45df3877-fe76-43fd-afeb-dd4de9d969c3"},{"cell_type":"code","source":"// Your suggestions?\n\n","metadata":{},"execution_count":null,"outputs":[],"id":"a217056c-feec-46b7-aaac-5d673e57c53f"},{"cell_type":"markdown","source":"- Our vectors store entries of type ```double```. Thus, that would be a fitting return type for the value of the computed Euclidean inner product. *We could hand the result back via a parameter, too. But that is probably less convenient here.*\n- We need two vectors for the operation, so the second one should be an input argument. But:\n - Use a reference to avoid copy generation.\n - Not going to change the vector, so that could be const.\n- Method will not change the VectorClass object itself either, so the method could be marked const, too.\n\nSo we end up with:\n\n**``` double innerProduct( const VectorClass& second ) const;```**","metadata":{},"id":"0c933e9f-554b-455c-b023-7f8e533e75dd"},{"cell_type":"markdown","source":"***\nOkay, so below is our extended ```VectorClass``` minus the actual implementation of the two methods:","metadata":{},"id":"274868db-03d2-4c69-99e2-cbedc0f31960"},{"cell_type":"code","source":"#include <iostream>\n#include <cassert>\n\nclass VectorClass{\n \npublic:\n\n // ------------------------------------------------\n // User should specify dimension at object creation\n // ------------------------------------------------\n VectorClass( unsigned int dim ) : dim_(dim) {\n \n // don't allow vectors with zero dimension\n assert( dim_ > 0 );\n\n // allocate memory (will throw an exception, if it fails)\n vec_ = new double[ dim_ ];\n \n // be talkative ;-)\n std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n }\n\n // ----------------------------------------------------------\n // Don't allow the default constructor\n // [prior to C++11 you would solve this by making it private]\n // ----------------------------------------------------------\n VectorClass() = delete;\n\n // ----------------------------------------------------------\n // Don't allow the following default copy constructor either \n // ----------------------------------------------------------\n VectorClass( VectorClass &other ) = delete;\n \n // ----------------------------------------------------------\n // We need to implement a destructor to free the dynamic memory again,\n // otherwise we easily produce memory leaks\n // ----------------------------------------------------------\n ~VectorClass() {\n std::cout << \"Going to delete memory starting at address \" << vec_ << std::endl;\n \n delete[] vec_;\n std::cout << \"An instance of VectorClass was destroyed and \"\n << dim_ * sizeof(double)\n << \" bytes freed.\" << std::endl;\n }\n\n // ----------------------------------------------------------\n // provide access to the vector's dimension\n // ----------------------------------------------------------\n unsigned int getDim() const { return dim_; }\n \n // ----------------------------------------------------------\n // overload the [] for accessing individual entries\n // ----------------------------------------------------------\n double& operator[] ( unsigned int index ) {\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n const double& operator[] ( unsigned int index ) const {\n assert( index != 0 && index <= dim_ );\n return vec_[index-1];\n }\n\n // ----------------------------------------------------------------------\n // pretty print vector to given output stream (default will be std::cout)\n // ----------------------------------------------------------------------\n void print( std::ostream &os = std::cout ) const {\n os << \"(\";\n for( unsigned int k = 0; k < dim_-1; k++ ) {\n os << vec_[k] << \", \";\n }\n os << vec_[dim_-1] << \")\" << std::endl;\n }\n \n // ----------------------------\n // scale vector with a constant\n // ----------------------------\n void scale( double factor );\n \n // ----------------------------------------------\n // compute Euclidean inner product of two vectors\n // ----------------------------------------------\n double innerProduct( const VectorClass& second ) const;\n \n // ----------------------------------------------------------------------\n // add to vectors together (that's actually a little bit tricky,\n // due to the question \"where to put the result?\"\n // for the moment leave it with adding another vector to the one on which\n // the method is called.\n // ----------------------------------------------------------------------\n void add( const VectorClass& other ) {\n\n // 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.vec_[k];\n }\n }\n \nprivate:\n unsigned int dim_; // dimension of vector\n double* vec_; // entries of vector\n\n};","metadata":{},"execution_count":1,"outputs":[],"id":"2bcf89a4-e232-47f8-afe2-a88897f13a52"},{"cell_type":"markdown","source":"***\nNow let us implement ```scale()```","metadata":{},"id":"7ab16ac5-7f91-43cc-9a68-2e8a52dd3058"},{"cell_type":"code","source":"void VectorClass::scale( const double factor ) {\n \n for( unsigned int k = 0; k < dim_; k++ ) {\n vec_[k] *= factor;\n }\n \n}","metadata":{},"execution_count":2,"outputs":[],"id":"816a0c45-6ff9-4d67-97e7-b076bd23526d"},{"cell_type":"markdown","source":"and ```innerProduct()```","metadata":{},"id":"c84995ae-c03e-41e7-a060-f5d7b4382c55"},{"cell_type":"code","source":"double VectorClass::innerProduct( const VectorClass& second ) const {\n\n double prod = 0.0;\n\n for( unsigned int k = 0; k < dim_; k++ ) {\n prod += vec_[k] * second.vec_[k]; // we have access to vec_, because we are of the same class\n }\n\n return prod;\n\n} ","metadata":{},"execution_count":3,"outputs":[],"id":"139b925e-5b80-4ea8-80e9-ffb1ace29ffc"},{"cell_type":"markdown","source":"A question on ```scale()```: Why did we not make it **```void scale( const double factor ) const```** ?","metadata":{},"id":"0b36c822-eae1-4b20-b7ad-1ff1938b723c"},{"cell_type":"markdown","source":"\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{},"id":"80b43239-51ec-4b63-af94-ce4e59fc6cc2"},{"cell_type":"markdown","source":"There are two aspects to this:\n1. The method itself cannot be marked ```const``` as it changes the state of our object, by changing values inside ```vec_```.\n1. We could mark ```factor``` as ```const```, but\n - It is a local variable, so changes to factor would have no effect outside the body of scale() anyhow.\n - For a basic datatype like double we are not sure if it would allow the compiler to perform some extra optimisations.\n - Finally it is more a question of whether you think it is worth the extra effort of marking it this way.","metadata":{},"id":"9e17a14b-096c-4abb-b806-8fedc733c9fc"},{"cell_type":"markdown","source":"***\nBelow follows our test-driver that should run through now the extension was completed","metadata":{},"id":"b44bb8cd-35c0-45d5-8c0e-ee80fed8d018"},{"cell_type":"code","source":"#include <cmath> // for using std::sqrt() below\n\nint main() {\n\n const unsigned int dim = 10;\n \n // set up 1st vector\n VectorClass myVec( dim );\n for( unsigned int idx = 1u; idx <= dim; idx++ ) {\n myVec[ idx ] = static_cast<double>( dim - idx + 1u );\n }\n myVec.print( std::cout );\n \n // set up 2nd vector\n VectorClass other( dim );\n for( unsigned int idx = 1u; 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 std::cout << \"\\nAdding both vectors gives: \";\n myVec.add( other );\n myVec.print();\n\n // now scale second vector by 0.5\n std::cout << \"\\nScaling the vector: \";\n other.print();\n std::cout << \"by 0.5 gives: \";\n other.scale( 0.5 );\n other.print();\n std::cout << std::endl;\n\n // compute the norm of the following vector\n VectorClass vec( 2 );\n vec[1] = 3.0;\n vec[2] = -4.0;\n double norm = vec.innerProduct( vec );\n norm = std::sqrt( norm );\n std::cout << \"Norm of vector \" << vec << \"is \" << norm << std::endl;\n vec.print();\n std::cout << \"is \" << norm << std::endl;\n \n std::cout << std::endl;\n // now destructors will be called\n}","metadata":{},"execution_count":4,"outputs":[],"id":"6fd51fae-99a1-476c-ad9f-59529b88811e"},{"cell_type":"code","source":"main();","metadata":{},"execution_count":5,"outputs":[{"name":"stdout","text":"An instance of VectorClass was generated. dim_ = 10\n(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\nAn instance of VectorClass was generated. dim_ = 10\n(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n\nAdding both vectors gives: (11, 11, 11, 11, 11, 11, 11, 11, 11, 11)\n\nScaling the vector: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\nby 0.5 gives: (0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5)\n\nAn instance of VectorClass was generated. dim_ = 2\nNorm of vector (3, -4)\nis 5\n\nGoing to delete memory starting at address 0x55e6cfd4e580\nAn instance of VectorClass was destroyed and 16 bytes freed.\nGoing to delete memory starting at address 0x55e6d09bdf70\nAn instance of VectorClass was destroyed and 80 bytes freed.\nGoing to delete memory starting at address 0x55e6d07d8a60\nAn instance of VectorClass was destroyed and 80 bytes freed.\n","output_type":"stream"}],"id":"9c827691-afe9-4cfb-b71d-4f01bccd09c2"},{"cell_type":"markdown","source":"***\nFinally, we need to answer question (3).\n\n * In our driver we just called ```vec.print()``` without providing an output stream as argument. How did that work?\n\n * At some point we change the implementation of VectorClass::print() to have a **default value** for its os argument: \n **```void print( std::ostream &os = std::cout ) const```**\n \n * Thus, if no argument is given, the compiler will automatically insert ```std::cout```.","metadata":{},"id":"067df258-3921-4328-bd14-cec60a4a02d8"},{"cell_type":"markdown","source":"#### Language Overview \n| language | optional arguments (w/ default values) | passing via keyword |\n|:---------| :-------------------------------------:|:-------------------:|\n| C | no (only via workarounds) | no |\n| C++ | yes | no |\n| Fortran | yes | yes |\n| Python | yes | yes |\n\nPassing via keyword means, that we can set some arguments explicitely by a **name=value** pair. \nPython example: ```print ('comma', 'separated', 'words', sep=', ')``` \n\n#### Optional Arguments in C++\n* In C++ there are some restrictions on the use of optional arguments.\n* Some of these are related to the fact that *passing via keyword* is not supported.\n* Rules are:\n - optional arguments must follow the 'regular' ones\n - if you do not supply a value for one optional argument, then you must also skip all arguments after that one","metadata":{},"id":"a59f1813-b205-439d-bb91-986e51df9336"},{"cell_type":"code","source":"#include <iostream>\n#include <string>\n\nvoid showVals( int a, int b = 2, double x = 1.0, std::string m = \"go\" ) {\n std::cout << \"(\"\n << a << \", \"\n << b << \", \"\n << x << \", \"\n << m << \")\" << std::endl;\n}","metadata":{},"execution_count":7,"outputs":[],"id":"aa9570b3-2a56-4b23-acaa-48c28a781870"},{"cell_type":"code","source":"int main() {\n\n showVals( 3 );\n showVals( 5, 3 );\n showVals( 1, 2, 3.0 );\n showVals( 4, 5, 6, \"Alte Gags\" );\n\n // showVals( 3, \"Polizei\" ); will not compile\n\n}\n\nmain();","metadata":{},"execution_count":11,"outputs":[{"name":"stdout","text":"(3, 2, 1, go)\n(5, 3, 1, go)\n(1, 2, 3, go)\n(4, 5, 6, Alte Gags)\n","output_type":"stream"}],"id":"ae9ceb03-fe74-4774-9d9c-b3d6d63d6710"},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[],"id":"c5eb79ba-2885-4de6-9f14-692c810222d5"}]} \ No newline at end of file +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5b54f8c4-59a0-4a5a-a15c-021d20ae3d22", + "metadata": {}, + "source": [ + "### Task #1\n", + "\n", + "In this task we want to further extend our ```VectorClass``` class. Specifically we would like add two methods and answer a question concerning ```VectorClass::print()```: \n", + " 1. Implement missing body of VectorClass::scale()\n", + " 1. Implement VectorClass::innerProduct(), how should the header look like?\n", + " 1. What happens, when we call myVec.print() without arguments in main?" + ] + }, + { + "cell_type": "markdown", + "id": "45df3877-fe76-43fd-afeb-dd4de9d969c3", + "metadata": {}, + "source": [ + "Let us start with (2). How should the interface for ```innerProduct()``` look like?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a217056c-feec-46b7-aaac-5d673e57c53f", + "metadata": {}, + "outputs": [], + "source": [ + "// Your suggestions?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "0c933e9f-554b-455c-b023-7f8e533e75dd", + "metadata": {}, + "source": [ + "- Our vectors store entries of type ```double```. Thus, that would be a fitting return type for the value of the computed Euclidean inner product. *We could hand the result back via a parameter, too. But that is probably less convenient here.*\n", + "- We need two vectors for the operation, so the second one should be an input argument. But:\n", + " - Use a reference to avoid copy generation.\n", + " - Not going to change the vector, so that could be const.\n", + "- Method will not change the VectorClass object itself either, so the method could be marked const, too.\n", + "\n", + "So we end up with:\n", + "\n", + "**``` double innerProduct( const VectorClass& second ) const;```**" + ] + }, + { + "cell_type": "markdown", + "id": "274868db-03d2-4c69-99e2-cbedc0f31960", + "metadata": {}, + "source": [ + "***\n", + "Okay, so below is our extended ```VectorClass``` minus the actual implementation of the two methods:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2bcf89a4-e232-47f8-afe2-a88897f13a52", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "#include <cassert>\n", + "\n", + "class VectorClass{\n", + " \n", + "public:\n", + "\n", + " // ------------------------------------------------\n", + " // User should specify dimension at object creation\n", + " // ------------------------------------------------\n", + " VectorClass( unsigned int dim ) : dim_(dim) {\n", + " \n", + " // don't allow vectors with zero dimension\n", + " assert( dim_ > 0 );\n", + "\n", + " // allocate memory (will throw an exception, if it fails)\n", + " vec_ = new double[ dim_ ];\n", + " \n", + " // be talkative ;-)\n", + " std::cout << \"An instance of VectorClass was generated. dim_ = \" << dim_ << std::endl;\n", + " }\n", + "\n", + " // ----------------------------------------------------------\n", + " // Don't allow the default constructor\n", + " // [prior to C++11 you would solve this by making it private]\n", + " // ----------------------------------------------------------\n", + " VectorClass() = delete;\n", + "\n", + " // ----------------------------------------------------------\n", + " // Don't allow the following default copy constructor either \n", + " // ----------------------------------------------------------\n", + " VectorClass( VectorClass &other ) = delete;\n", + " \n", + " // ----------------------------------------------------------\n", + " // We need to implement a destructor to free the dynamic memory again,\n", + " // otherwise we easily produce memory leaks\n", + " // ----------------------------------------------------------\n", + " ~VectorClass() {\n", + " std::cout << \"Going to delete memory starting at address \" << vec_ << std::endl;\n", + " \n", + " delete[] vec_;\n", + " std::cout << \"An instance of VectorClass was destroyed and \"\n", + " << dim_ * sizeof(double)\n", + " << \" bytes freed.\" << std::endl;\n", + " }\n", + "\n", + " // ----------------------------------------------------------\n", + " // provide access to the vector's dimension\n", + " // ----------------------------------------------------------\n", + " unsigned int getDim() const { return dim_; }\n", + " \n", + " // ----------------------------------------------------------\n", + " // overload the [] for accessing individual entries\n", + " // ----------------------------------------------------------\n", + " double& operator[] ( unsigned int index ) {\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " const double& operator[] ( unsigned int index ) const {\n", + " assert( index != 0 && index <= dim_ );\n", + " return vec_[index-1];\n", + " }\n", + "\n", + " // ----------------------------------------------------------------------\n", + " // pretty print vector to given output stream (default will be std::cout)\n", + " // ----------------------------------------------------------------------\n", + " void print( std::ostream &os = std::cout ) const {\n", + " os << \"(\";\n", + " for( unsigned int k = 0; k < dim_-1; k++ ) {\n", + " os << vec_[k] << \", \";\n", + " }\n", + " os << vec_[dim_-1] << \")\" << std::endl;\n", + " }\n", + " \n", + " // ----------------------------\n", + " // scale vector with a constant\n", + " // ----------------------------\n", + " void scale( double factor );\n", + " \n", + " // ----------------------------------------------\n", + " // compute Euclidean inner product of two vectors\n", + " // ----------------------------------------------\n", + " double innerProduct( const VectorClass& second ) const;\n", + " \n", + " // ----------------------------------------------------------------------\n", + " // add to vectors together (that's actually a little bit tricky,\n", + " // due to the question \"where to put the result?\"\n", + " // for the moment leave it with adding another vector to the one on which\n", + " // the method is called.\n", + " // ----------------------------------------------------------------------\n", + " void add( const VectorClass& other ) {\n", + "\n", + " // make sure that input vector has correct length\n", + " assert( other.dim_ == dim_ );\n", + " for( unsigned int k = 0; k < dim_; k++ ) {\n", + " vec_[k] += other.vec_[k];\n", + " }\n", + " }\n", + " \n", + "private:\n", + " unsigned int dim_; // dimension of vector\n", + " double* vec_; // entries of vector\n", + "\n", + "};" + ] + }, + { + "cell_type": "markdown", + "id": "7ab16ac5-7f91-43cc-9a68-2e8a52dd3058", + "metadata": {}, + "source": [ + "***\n", + "Now let us implement ```scale()```" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "816a0c45-6ff9-4d67-97e7-b076bd23526d", + "metadata": {}, + "outputs": [], + "source": [ + "void VectorClass::scale( const double factor ) {\n", + " \n", + " for( unsigned int k = 0; k < dim_; k++ ) {\n", + " vec_[k] *= factor;\n", + " }\n", + " \n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "c84995ae-c03e-41e7-a060-f5d7b4382c55", + "metadata": {}, + "source": [ + "and ```innerProduct()```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "139b925e-5b80-4ea8-80e9-ffb1ace29ffc", + "metadata": {}, + "outputs": [], + "source": [ + "double VectorClass::innerProduct( const VectorClass& second ) const {\n", + "\n", + " double prod = 0.0;\n", + "\n", + " for( unsigned int k = 0; k < dim_; k++ ) {\n", + " prod += vec_[k] * second.vec_[k]; // we have access to vec_, because we are of the same class\n", + " }\n", + "\n", + " return prod;\n", + "\n", + "} " + ] + }, + { + "cell_type": "markdown", + "id": "0b36c822-eae1-4b20-b7ad-1ff1938b723c", + "metadata": {}, + "source": [ + "A question on ```scale()```: Why did we not make it **```void scale( const double factor ) const```** ?" + ] + }, + { + "cell_type": "markdown", + "id": "80b43239-51ec-4b63-af94-ce4e59fc6cc2", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "9e17a14b-096c-4abb-b806-8fedc733c9fc", + "metadata": {}, + "source": [ + "There are two aspects to this:\n", + "1. The method itself cannot be marked ```const``` as it changes the state of our object, by changing values inside ```vec_```.\n", + "1. We could mark ```factor``` as ```const```, but\n", + " - It is a local variable, so changes to factor would have no effect outside the body of scale() anyhow.\n", + " - For a basic datatype like double we are not sure if it would allow the compiler to perform some extra optimisations.\n", + " - Finally it is more a question of whether you think it is worth the extra effort of marking it this way." + ] + }, + { + "cell_type": "markdown", + "id": "b44bb8cd-35c0-45d5-8c0e-ee80fed8d018", + "metadata": {}, + "source": [ + "***\n", + "Below follows our test-driver that should run through now the extension was completed" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6fd51fae-99a1-476c-ad9f-59529b88811e", + "metadata": {}, + "outputs": [], + "source": [ + "#include <cmath> // for using std::sqrt() below\n", + "\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 = 1u; idx <= dim; idx++ ) {\n", + " myVec[ idx ] = static_cast<double>( dim - idx + 1u );\n", + " }\n", + " myVec.print( std::cout );\n", + " \n", + " // set up 2nd vector\n", + " VectorClass other( dim );\n", + " for( unsigned int idx = 1u; 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", + " std::cout << \"\\nAdding both vectors gives: \";\n", + " myVec.add( other );\n", + " myVec.print();\n", + "\n", + " // now scale second vector by 0.5\n", + " std::cout << \"\\nScaling the vector: \";\n", + " other.print();\n", + " std::cout << \"by 0.5 gives: \";\n", + " other.scale( 0.5 );\n", + " other.print();\n", + " std::cout << std::endl;\n", + "\n", + " // compute the norm of the following vector\n", + " VectorClass vec( 2 );\n", + " vec[1] = 3.0;\n", + " vec[2] = -4.0;\n", + " double norm = vec.innerProduct( vec );\n", + " norm = std::sqrt( norm );\n", + " std::cout << \"Norm of vector \" << vec << \"is \" << norm << std::endl;\n", + " vec.print();\n", + " std::cout << \"is \" << norm << std::endl;\n", + " \n", + " std::cout << std::endl;\n", + " // now destructors will be called\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "9c827691-afe9-4cfb-b71d-4f01bccd09c2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "An instance of VectorClass was generated. dim_ = 10\n", + "(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n", + "An instance of VectorClass was generated. dim_ = 10\n", + "(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n", + "\n", + "Adding both vectors gives: (11, 11, 11, 11, 11, 11, 11, 11, 11, 11)\n", + "\n", + "Scaling the vector: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n", + "by 0.5 gives: (0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5)\n", + "\n", + "An instance of VectorClass was generated. dim_ = 2\n", + "Norm of vector (3, -4)\n", + "is 5\n", + "\n", + "Going to delete memory starting at address 0x55e6cfd4e580\n", + "An instance of VectorClass was destroyed and 16 bytes freed.\n", + "Going to delete memory starting at address 0x55e6d09bdf70\n", + "An instance of VectorClass was destroyed and 80 bytes freed.\n", + "Going to delete memory starting at address 0x55e6d07d8a60\n", + "An instance of VectorClass was destroyed and 80 bytes freed.\n" + ] + } + ], + "source": [ + "main();" + ] + }, + { + "cell_type": "markdown", + "id": "067df258-3921-4328-bd14-cec60a4a02d8", + "metadata": {}, + "source": [ + "***\n", + "Finally, we need to answer question (3).\n", + "\n", + " * In our driver we just called ```vec.print()``` without providing an output stream as argument. How did that work?\n", + "\n", + " * At some point we change the implementation of VectorClass::print() to have a **default value** for its os argument: \n", + " **```void print( std::ostream &os = std::cout ) const```**\n", + " \n", + " * Thus, if no argument is given, the compiler will automatically insert ```std::cout```." + ] + }, + { + "cell_type": "markdown", + "id": "a59f1813-b205-439d-bb91-986e51df9336", + "metadata": {}, + "source": [ + "#### Language Overview \n", + "| language | optional arguments (w/ default values) | passing via keyword |\n", + "|:---------| :-------------------------------------:|:-------------------:|\n", + "| C | no (only via workarounds) | no |\n", + "| C++ | yes | no |\n", + "| Fortran | yes | yes |\n", + "| Python | yes | yes |\n", + "\n", + "Passing via keyword means, that we can set some arguments explicitely by a **name=value** pair. \n", + "Python example: ```print ('comma', 'separated', 'words', sep=', ')``` \n", + "\n", + "#### Optional Arguments in C++\n", + "* In C++ there are some restrictions on the use of optional arguments.\n", + "* Some of these are related to the fact that *passing via keyword* is not supported.\n", + "* Rules are:\n", + " - optional arguments must follow the 'regular' ones\n", + " - if you do not supply a value for one optional argument, then you must also skip all arguments after that one" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "aa9570b3-2a56-4b23-acaa-48c28a781870", + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "#include <string>\n", + "\n", + "void showVals( int a, int b = 2, double x = 1.0, std::string m = \"go\" ) {\n", + " std::cout << \"(\"\n", + " << a << \", \"\n", + " << b << \", \"\n", + " << x << \", \"\n", + " << m << \")\" << std::endl;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ae9ceb03-fe74-4774-9d9c-b3d6d63d6710", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, 2, 1, go)\n", + "(5, 3, 1, go)\n", + "(1, 2, 3, go)\n", + "(4, 5, 6, Alte Gags)\n" + ] + } + ], + "source": [ + "int main() {\n", + "\n", + " showVals( 3 );\n", + " showVals( 5, 3 );\n", + " showVals( 1, 2, 3.0 );\n", + " showVals( 4, 5, 6, \"Alte Gags\" );\n", + "\n", + " // showVals( 3, \"Polizei\" ); will not compile\n", + "\n", + "}\n", + "\n", + "main();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5eb79ba-2885-4de6-9f14-692c810222d5", + "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 +}