Skip to content
Snippets Groups Projects
Commit ce743007 authored by Marcus Mohr's avatar Marcus Mohr
Browse files

Perform updates and corrections

Major correction is to fix the wrong statement that objects would not
have access to private members of the class in other objects of the same
class. We already used that in Task#1. We now also make use of this in
the final version of VectorClass in notebook #4. Besides this updates
are mainly w.r.t. typos and formatting.
parent fa4d97bd
Branches
Tags
No related merge requests found
Source diff could not be displayed: it is too large. Options to address this: view the blob.
%% Cell type:markdown id:e04e0b83-753f-4a58-bce3-3746e7c69650 tags: %% Cell type:markdown id:e04e0b83-753f-4a58-bce3-3746e7c69650 tags:
### Friendship ### Friendship
%% Cell type:markdown id:6c224ee8-f4c0-495c-8261-6d2c17f845a6 tags: %% Cell type:markdown id:6c224ee8-f4c0-495c-8261-6d2c17f845a6 tags:
* In many situations we tend to make the data members of our classes **private** (or protected in the case of inheritance). * In many situations we tend to make the data members of our classes **private** (or protected in the case of inheritance).
* 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. * 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.)*
* Sometimes this is too restrictive, though. We might need to provide direct access to our members for selected **friends**. * Sometimes this is too restrictive, though. We might need to provide direct access to our members for selected **friends**.
* A typical example is, when we want to overload the ```<<``` operator, to be able to place our object into an output stream. * 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 tags: %% Cell type:markdown id:ff1a3263-e349-4840-af2f-ad90fde352ac tags:
*** ***
Let us create a simpe demo class Let us create a simpe demo class
%% Cell type:code id:cebe299d-3bcc-4a57-af69-8aed41401244 tags: %% Cell type:code id:cebe299d-3bcc-4a57-af69-8aed41401244 tags:
``` C++11 ``` C++11
class myTuple { class myTuple {
int fir; int fir;
int sec; int sec;
public: public:
myTuple( int fir, int sec ) : fir(fir), sec(sec) {}; myTuple( int fir, int sec ) : fir(fir), sec(sec) {};
}; };
``` ```
%% Cell type:markdown id:97622c4c-2eba-47cd-8dbb-c2fe9963dbc3 tags: %% Cell type:markdown id:97622c4c-2eba-47cd-8dbb-c2fe9963dbc3 tags:
and try to test-run it and try to test-run it
%% Cell type:code id:7b80f338-bd48-4699-81aa-fbae245a3a04 tags: %% Cell type:code id:7b80f338-bd48-4699-81aa-fbae245a3a04 tags:
``` C++11 ``` C++11
#include <iostream> #include <iostream>
int main() { int main() {
myTuple obj( 3, 5 ); myTuple obj( 3, 5 );
std::cout << "Pair is: " << obj << std::endl; std::cout << "Pair is: " << obj << std::endl;
} }
main(); main();
``` ```
%% Output %% Output
input_line_9:3:28: error: invalid operands to binary expression ('basic_ostream<char, std::char_traits<char> >' and '__cling_N52::myTuple') input_line_9:3:28: error: invalid operands to binary expression ('basic_ostream<char,
std::cout << "Pair is: " << obj << std::endl; std::char_traits<char> >' and '__cling_N52::myTuple')
~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~ std::cout << "Pair is: " << obj << std::endl;
/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 &  ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~
operator<<(const void* __p) /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: 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
/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 &
operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) operator<<(const void* __p)
^  ^
/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 /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(__ostream_type& (*__pf)(__ostream_type&)) to 'const std::error_code' for 2nd argument
^ operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
/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  ^
operator<<(__ios_type& (*__pf)(__ios_type&)) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'std::basic_ostream<char, std::char_traits<char> >::__ostream_type
/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 &(*)(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &)'
operator<<(ios_base& (*__pf) (ios_base&)) (aka 'basic_ostream<char, std::char_traits<char> >
^ &(*)(basic_ostream<char, std::char_traits<char> > &)') for 1st argument
/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 operator<<(__ostream_type& (*__pf)(__ostream_type&))
operator<<(long __n)  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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 to 'std::basic_ostream<char, std::char_traits<char> >::__ios_type
operator<<(unsigned long __n) &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)'
^ (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char,
/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 std::char_traits<char> > &)') for 1st argument
operator<<(bool __n) operator<<(__ios_type& (*__pf)(__ios_type&))
^  ^
/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 /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(short __n); to 'std::ios_base &(*)(std::ios_base &)' for 1st argument
^ operator<<(ios_base& (*__pf) (ios_base&))
/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  ^
operator<<(unsigned short __n) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'long' for 1st argument
/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 operator<<(long __n)
operator<<(int __n);  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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 to 'unsigned long' for 1st argument
operator<<(unsigned int __n) operator<<(unsigned long __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 /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(long long __n) to 'bool' for 1st argument
^ operator<<(bool __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  ^
operator<<(unsigned long long __n) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'short' for 1st argument
/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 operator<<(short __n);
operator<<(double __f)  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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 to 'unsigned short' for 1st argument
operator<<(float __f) operator<<(unsigned short __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 /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(long double __f) to 'int' for 1st argument
^ operator<<(int __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  ^
operator<<(__streambuf_type* __sb); /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'unsigned int' for 1st argument
/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 operator<<(unsigned int __n)
operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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 to 'long long' for 1st argument
operator<<(basic_ostream<char, _Traits>& __out, char __c) operator<<(long long __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 /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(basic_ostream<char, _Traits>& __out, signed char __c) to 'unsigned long long' for 1st argument
^ operator<<(unsigned long long __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  ^
operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'double' for 1st argument
/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 operator<<(double __f)
operator<<(basic_ostream<char, _Traits>& __out, const char* __s)  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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 to 'float' for 1st argument
operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) operator<<(float __f)
^  ^
/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 /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) to 'long double' for 1st argument
^ operator<<(long double __f)
/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  ^
operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *'
/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') (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument
operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) operator<<(__streambuf_type* __sb);
^  ^
/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' /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(basic_ostream<_CharT, _Traits>& __os, to 'char' for 2nd argument
^ operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)
/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'  ^
operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'char' for 2nd argument
/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] operator<<(basic_ostream<char, _Traits>& __out, char __c)
operator<<(_Ostream&& __os, const _Tp& __x)  ^
^
/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' /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
operator<<(std::basic_ostream<_Ch, _Tr>& __os, to 'signed char' for 2nd argument
^ operator<<(basic_ostream<char, _Traits>& __out, signed char __c)
/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'  ^
_DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
^ to 'unsigned char' for 2nd argument
/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' operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)
operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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' to 'const char *' for 2nd argument
/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' operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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' to 'const signed char *' for 2nd argument
/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' operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)
operator _Op(const typename _Dom::value_type& __t, \  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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' to 'const unsigned char *' for 2nd argument
/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' operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)
operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \  ^
^ /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: note: candidate function not viable: no known conversion from '__cling_N52::myTuple'
/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' to 'const char *' for 2nd argument
/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' operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
operator _Op(const valarray<typename _Dom::value_type>& __v, \  ^
^ /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: note: candidate template ignored: deduced conflicting types for parameter '_CharT'
/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' ('char' vs. '__cling_N52::myTuple')
_DEFINE_BINARY_OPERATOR(<<, __shift_left) operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
^  ^
/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' /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: note: candidate template ignored: could not match 'basic_string<type-parameter-0-0,
operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ type-parameter-0-1, type-parameter-0-2>' against '__cling_N52::myTuple'
^ operator<<(basic_ostream<_CharT, _Traits>& __os,
/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'  ^
/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' /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: note: candidate template ignored: could not match 'const _CharT *' against
operator _Op(const valarray<_Tp>& __v, \ '__cling_N52::myTuple'
^ operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
/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'  ^
/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' /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: note: candidate template ignored: requirement
operator _Op(const typename valarray<_Tp>::value_type& __t, \ '__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]
operator<<(_Ostream&& __os, const _Tp& __x)
 ^
/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: note: candidate template ignored: could not match '__shared_ptr<type-parameter-0-2,
_Lp>' against '__cling_N52::myTuple'
operator<<(std::basic_ostream<_Ch, _Tr>& __os,
 ^
/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: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'
_DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)
 ^
/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: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'
operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \
 ^
/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: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'
/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: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'
operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \
 ^
/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: note: candidate template ignored: could not match '_Expr<type-parameter-0-0, typename
type-parameter-0-0::value_type>' against '__cling_N52::myTuple'
/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: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'
operator _Op(const typename _Dom::value_type& __t, \
 ^
/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: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'
/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: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'
operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \
 ^
/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: note: candidate template ignored: could not match '_Expr<type-parameter-0-0, typename
type-parameter-0-0::value_type>' against '__cling_N52::myTuple'
/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: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'
operator _Op(const valarray<typename _Dom::value_type>& __v, \
 ^
/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: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'
_DEFINE_BINARY_OPERATOR(<<, __shift_left)
^
/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: note: expanded from macro '_DEFINE_BINARY_OPERATOR'
operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \
 ^
/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: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'
/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: note: expanded from macro '_DEFINE_BINARY_OPERATOR'
operator _Op(const valarray<_Tp>& __v, \
 ^
/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: note: candidate template ignored: could not match 'valarray<type-parameter-0-0>'
against '__cling_N52::myTuple'
/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: note: expanded from macro '_DEFINE_BINARY_OPERATOR'
operator _Op(const typename valarray<_Tp>::value_type& __t, \
 ^

Interpreter Error: Interpreter Error:
%% Cell type:markdown id:8b28c2a6-533e-478b-91e1-b63270121d6c tags: %% Cell type:markdown id:8b28c2a6-533e-478b-91e1-b63270121d6c tags:
Okay that obviously did not work. Problem is that ```<<``` does not know how to work with objects of type ```myTuple```. Okay that obviously did not work. Problem is that ```<<``` does not know how to work with objects of type ```myTuple```.
* We can fix this by implementing a version of ```<<``` that understands it. * We can fix this by implementing a version of ```<<``` that understands it.
* 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 ```<<```. * 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 id:8dfa7a1c-28d8-4de1-ae19-bdb2a6d3e48e tags: %% Cell type:code id:8dfa7a1c-28d8-4de1-ae19-bdb2a6d3e48e tags:
``` C++11 ``` C++11
%%file myTuple.cpp %%file myTuple.cpp
#include <iostream> #include <iostream>
class myTuple { class myTuple {
int fir; int fir;
int sec; int sec;
public: public:
myTuple( int fir, int sec ) : fir(fir), sec(sec) {}; myTuple( int fir, int sec ) : fir(fir), sec(sec) {};
}; };
std::ostream& operator << ( std::ostream &os, const myTuple& tup ) std::ostream& operator << ( std::ostream &os, const myTuple& tup )
{ {
os << "( " << tup.fir << " , " << tup.sec << " )"; os << "( " << tup.fir << " , " << tup.sec << " )";
// necessary for chaining: // necessary for chaining:
return os; return os;
} }
``` ```
%% Output %% Output
Writing myTuple.cpp Overwriting myTuple.cpp
%% Cell type:code id:25e56a5e-6c64-4d77-9a81-5d808f2b63b3 tags: %% Cell type:code id:25e56a5e-6c64-4d77-9a81-5d808f2b63b3 tags:
``` C++11 ``` C++11
!g++ -Wall -Wextra -c myTuple.cpp !g++ -Wall -Wextra -c myTuple.cpp
``` ```
%% Output %% Output
myTuple.cpp: In function ‘std::ostream& operator<<(std::ostream&, const myTuple&)’: myTuple.cpp: In function ‘std::ostream& operator<<(std::ostream&, const myTuple&)’:
myTuple.cpp:16:23: error: ‘int myTuple::fir’ is private within this context myTuple.cpp:16:23: error: ‘int myTuple::fir’ is private within this context
os << "( " << tup.fir << " , " << tup.sec << " )"; os << "( " << tup.fir << " , " << tup.sec << " )";
^~~ ^~~
myTuple.cpp:6:7: note: declared private here myTuple.cpp:6:7: note: declared private here
int fir; int fir;
^~~ ^~~
myTuple.cpp:16:43: error: ‘int myTuple::sec’ is private within this context myTuple.cpp:16:43: error: ‘int myTuple::sec’ is private within this context
os << "( " << tup.fir << " , " << tup.sec << " )"; os << "( " << tup.fir << " , " << tup.sec << " )";
^~~ ^~~
myTuple.cpp:7:7: note: declared private here myTuple.cpp:7:7: note: declared private here
int sec; int sec;
^~~ ^~~
%% Cell type:markdown id:092b284c-9b78-4ea9-9b9a-f43cc5f32612 tags: %% Cell type:markdown id:092b284c-9b78-4ea9-9b9a-f43cc5f32612 tags:
* That was to be expected. The attributes ```fir``` and ```sec``` of ```myTuple``` are private. * That was to be expected. The attributes ```fir``` and ```sec``` of ```myTuple``` are private.
* However, we do not want to make them accessible to everyone, just for the sake of one special function/operator. * However, we do not want to make them accessible to everyone, just for the sake of one special function/operator.
* But, we can do so **selectively**, with the friend statement. * But, we can do so **selectively**, with the friend statement.
%% Cell type:code id:ff341d41-7aa2-4f87-92f2-e189dd448d68 tags: %% Cell type:code id:ff341d41-7aa2-4f87-92f2-e189dd448d68 tags:
``` C++11 ``` C++11
%%file myTuple.cpp %%file myTuple.cpp
#include <iostream> #include <iostream>
class myTuple { class myTuple {
int fir; int fir;
int sec; int sec;
friend std::ostream& operator << ( std::ostream&, const myTuple& ); friend std::ostream& operator << ( std::ostream&, const myTuple& );
public: public:
myTuple( int fir, int sec ) : fir(fir), sec(sec) {}; myTuple( int fir, int sec ) : fir(fir), sec(sec) {};
}; };
std::ostream& operator << ( std::ostream &os, const myTuple& tup ) std::ostream& operator << ( std::ostream &os, const myTuple& tup )
{ {
os << "( " << tup.fir << " , " << tup.sec << " )" << std::endl; os << "( " << tup.fir << " , " << tup.sec << " )" << std::endl;
// necessary for chaining: // necessary for chaining:
return os; return os;
} }
int main() { int main() {
myTuple obj( 3, 5 ); myTuple obj( 3, 5 );
std::cout << "Pair is: " << obj << std::endl; std::cout << "Pair is: " << obj << std::endl;
} }
``` ```
%% Output %% Output
Overwriting myTuple.cpp Overwriting myTuple.cpp
%% Cell type:code id:c8560f81-10ef-4203-b3f3-8046255be25a tags: %% Cell type:code id:c8560f81-10ef-4203-b3f3-8046255be25a tags:
``` C++11 ``` C++11
!g++ -Wall -Wextra myTuple.cpp !g++ -Wall -Wextra myTuple.cpp
``` ```
%% Cell type:code id:6a5f1cb3-7891-4cb8-b8ce-d3f6aa996ecc tags: %% Cell type:code id:6a5f1cb3-7891-4cb8-b8ce-d3f6aa996ecc tags:
``` C++11 ``` C++11
!./a.out !./a.out
``` ```
%% Output %% Output
Pair is: ( 3 , 5 ) Pair is: ( 3 , 5 )
%% Cell type:code id:94e6f340-7a06-4c59-8889-5088e41712f2 tags: %% Cell type:code id:94e6f340-7a06-4c59-8889-5088e41712f2 tags:
``` C++11 ``` C++11
``` ```
......
%% Cell type:markdown id:5b54f8c4-59a0-4a5a-a15c-021d20ae3d22 tags: %% Cell type:markdown id:5b54f8c4-59a0-4a5a-a15c-021d20ae3d22 tags:
### Task #1 ### Task #1
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()```: 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()```:
1. Implement missing body of VectorClass::scale() 1. Implement missing body of VectorClass::scale()
1. Implement VectorClass::innerProduct(), how should the header look like? 1. Implement VectorClass::innerProduct(), how should the header look like?
1. What happens, when we call myVec.print() without arguments in main? 1. What happens, when we call myVec.print() without arguments in main?
%% Cell type:markdown id:45df3877-fe76-43fd-afeb-dd4de9d969c3 tags: %% Cell type:markdown id:45df3877-fe76-43fd-afeb-dd4de9d969c3 tags:
Let us start with (2). How should the interface for ```innerProduct()``` look like? Let us start with (2). How should the interface for ```innerProduct()``` look like?
%% Cell type:code id:a217056c-feec-46b7-aaac-5d673e57c53f tags: %% Cell type:code id:a217056c-feec-46b7-aaac-5d673e57c53f tags:
``` C++17 ``` C++17
// Your suggestions? // Your suggestions?
``` ```
%% Cell type:markdown id:0c933e9f-554b-455c-b023-7f8e533e75dd tags: %% Cell type:markdown id:0c933e9f-554b-455c-b023-7f8e533e75dd tags:
- 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.* - 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.*
- We need two vectors for the operation, so the second one should be an input argument. But: - We need two vectors for the operation, so the second one should be an input argument. But:
- Use a reference to avoid copy generation. - Use a reference to avoid copy generation.
- Not going to change the vector, so that could be const. - Not going to change the vector, so that could be const.
- Method will not change the VectorClass object itself either, so the method could be marked const, too. - Method will not change the VectorClass object itself either, so the method could be marked const, too.
So we end up with: So we end up with:
**``` double innerProduct( const VectorClass& second ) const;```** **``` double innerProduct( const VectorClass& second ) const;```**
%% Cell type:markdown id:274868db-03d2-4c69-99e2-cbedc0f31960 tags: %% Cell type:markdown id:274868db-03d2-4c69-99e2-cbedc0f31960 tags:
*** ***
Okay, so below is our extended ```VectorClass``` minus the actual implementation of the two methods: Okay, so below is our extended ```VectorClass``` minus the actual implementation of the two methods:
%% Cell type:code id:2bcf89a4-e232-47f8-afe2-a88897f13a52 tags: %% Cell type:code id:2bcf89a4-e232-47f8-afe2-a88897f13a52 tags:
``` C++17 ``` C++17
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
class VectorClass{ class VectorClass{
public: public:
// ------------------------------------------------ // ------------------------------------------------
// User should specify dimension at object creation // User should specify dimension at object creation
// ------------------------------------------------ // ------------------------------------------------
VectorClass( unsigned int dim ) : dim_(dim) { VectorClass( unsigned int dim ) : dim_(dim) {
// don't allow vectors with zero dimension // don't allow vectors with zero dimension
assert( dim_ > 0 ); assert( dim_ > 0 );
// allocate memory (will throw an exception, if it fails) // allocate memory (will throw an exception, if it fails)
vec_ = new double[ dim_ ]; vec_ = new double[ dim_ ];
// be talkative ;-) // be talkative ;-)
std::cout << "An instance of VectorClass was generated. dim_ = " << dim_ << std::endl; std::cout << "An instance of VectorClass was generated. dim_ = " << dim_ << std::endl;
} }
// ---------------------------------------------------------- // ----------------------------------------------------------
// Don't allow the default constructor // Don't allow the default constructor
// [prior to C++11 you would solve this by making it private] // [prior to C++11 you would solve this by making it private]
// ---------------------------------------------------------- // ----------------------------------------------------------
VectorClass() = delete; VectorClass() = delete;
// ---------------------------------------------------------- // ----------------------------------------------------------
// Don't allow the following default copy constructor either // Don't allow the following default copy constructor either
// ---------------------------------------------------------- // ----------------------------------------------------------
VectorClass( VectorClass &other ) = delete; VectorClass( VectorClass &other ) = delete;
// ---------------------------------------------------------- // ----------------------------------------------------------
// We need to implement a destructor to free the dynamic memory again, // We need to implement a destructor to free the dynamic memory again,
// otherwise we easily produce memory leaks // otherwise we easily produce memory leaks
// ---------------------------------------------------------- // ----------------------------------------------------------
~VectorClass() { ~VectorClass() {
std::cout << "Going to delete memory starting at address " << vec_ << std::endl; std::cout << "Going to delete memory starting at address " << vec_ << std::endl;
delete[] vec_; delete[] vec_;
std::cout << "An instance of VectorClass was destroyed and " std::cout << "An instance of VectorClass was destroyed and "
<< dim_ * sizeof(double) << dim_ * sizeof(double)
<< " bytes freed." << std::endl; << " bytes freed." << std::endl;
} }
// ---------------------------------------------------------- // ----------------------------------------------------------
// provide access to the vector's dimension // provide access to the vector's dimension
// ---------------------------------------------------------- // ----------------------------------------------------------
unsigned int getDim() const { return dim_; } unsigned int getDim() const { return dim_; }
// ---------------------------------------------------------- // ----------------------------------------------------------
// overload the [] for accessing individual entries // overload the [] for accessing individual entries
// ---------------------------------------------------------- // ----------------------------------------------------------
double& operator[] ( unsigned int index ) { double& operator[] ( unsigned int index ) {
assert( index != 0 && index <= dim_ ); assert( index != 0 && index <= dim_ );
return vec_[index-1]; return vec_[index-1];
} }
const double& operator[] ( unsigned int index ) const { const double& operator[] ( unsigned int index ) const {
assert( index != 0 && index <= dim_ ); assert( index != 0 && index <= dim_ );
return vec_[index-1]; return vec_[index-1];
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// pretty print vector to given output stream (default will be std::cout) // pretty print vector to given output stream (default will be std::cout)
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
void print( std::ostream &os = std::cout ) const { void print( std::ostream &os = std::cout ) const {
os << "("; os << "(";
for( unsigned int k = 0; k < dim_-1; k++ ) { for( unsigned int k = 0; k < dim_-1; k++ ) {
os << vec_[k] << ", "; os << vec_[k] << ", ";
} }
os << vec_[dim_-1] << ")" << std::endl; os << vec_[dim_-1] << ")" << std::endl;
} }
// ---------------------------- // ----------------------------
// scale vector with a constant // scale vector with a constant
// ---------------------------- // ----------------------------
void scale( double factor ); void scale( double factor );
// ---------------------------------------------- // ----------------------------------------------
// compute Euclidean inner product of two vectors // compute Euclidean inner product of two vectors
// ---------------------------------------------- // ----------------------------------------------
double innerProduct( const VectorClass& second ) const; double innerProduct( const VectorClass& second ) const;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// add to vectors together (that's actually a little bit tricky, // add to vectors together (that's actually a little bit tricky,
// due to the question "where to put the result?" // due to the question "where to put the result?"
// for the moment leave it with adding another vector to the one on which // for the moment leave it with adding another vector to the one on which
// the method is called. // the method is called.
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
void add( const VectorClass& other ) { void add( const VectorClass& other ) {
// make sure that input vector has correct length // make sure that input vector has correct length
assert( other.getDim() == dim_ ); assert( other.dim_ == dim_ );
for( unsigned int k = 0; k < dim_; k++ ) { for( unsigned int k = 0; k < dim_; k++ ) {
vec_[k] += other.vec_[k]; vec_[k] += other.vec_[k];
} }
} }
private: private:
unsigned int dim_; // dimension of vector unsigned int dim_; // dimension of vector
double* vec_; // entries of vector double* vec_; // entries of vector
}; };
``` ```
%% Cell type:markdown id:7ab16ac5-7f91-43cc-9a68-2e8a52dd3058 tags: %% Cell type:markdown id:7ab16ac5-7f91-43cc-9a68-2e8a52dd3058 tags:
*** ***
Now let us implement ```scale()``` Now let us implement ```scale()```
%% Cell type:code id:816a0c45-6ff9-4d67-97e7-b076bd23526d tags: %% Cell type:code id:816a0c45-6ff9-4d67-97e7-b076bd23526d tags:
``` C++17 ``` C++17
void VectorClass::scale( const double factor ) { void VectorClass::scale( const double factor ) {
for( unsigned int k = 0; k < dim_; k++ ) { for( unsigned int k = 0; k < dim_; k++ ) {
vec_[k] *= factor; vec_[k] *= factor;
} }
} }
``` ```
%% Cell type:markdown id:c84995ae-c03e-41e7-a060-f5d7b4382c55 tags: %% Cell type:markdown id:c84995ae-c03e-41e7-a060-f5d7b4382c55 tags:
and ```innerProduct()``` and ```innerProduct()```
%% Cell type:code id:139b925e-5b80-4ea8-80e9-ffb1ace29ffc tags: %% Cell type:code id:139b925e-5b80-4ea8-80e9-ffb1ace29ffc tags:
``` C++17 ``` C++17
double VectorClass::innerProduct( const VectorClass& second ) const { double VectorClass::innerProduct( const VectorClass& second ) const {
double prod = 0.0; double prod = 0.0;
for( unsigned int k = 0; k < dim_; k++ ) { for( unsigned int k = 0; k < dim_; k++ ) {
prod += vec_[k] * second.vec_[k]; // we have access to vec_, because we are of the same class prod += vec_[k] * second.vec_[k]; // we have access to vec_, because we are of the same class
} }
return prod; return prod;
} }
``` ```
%% Cell type:markdown id:0b36c822-eae1-4b20-b7ad-1ff1938b723c tags: %% Cell type:markdown id:0b36c822-eae1-4b20-b7ad-1ff1938b723c tags:
A question on ```scale()```: Why did we not make it **```void scale( const double factor ) const```** ? 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 tags: %% Cell type:markdown id:80b43239-51ec-4b63-af94-ce4e59fc6cc2 tags:
%% Cell type:markdown id:9e17a14b-096c-4abb-b806-8fedc733c9fc tags: %% Cell type:markdown id:9e17a14b-096c-4abb-b806-8fedc733c9fc tags:
There are two aspects to this: There are two aspects to this:
1. The method itself cannot be marked ```const``` as it changes the state of our object, by changing values inside ```vec_```. 1. The method itself cannot be marked ```const``` as it changes the state of our object, by changing values inside ```vec_```.
1. We could mark ```factor``` as ```const```, but 1. We could mark ```factor``` as ```const```, but
- It is a local variable, so changes to factor would have no effect outside the body of scale() anyhow. - It is a local variable, so changes to factor would have no effect outside the body of scale() anyhow.
- For a basic datatype like double we are not sure if it would allow the compiler to perform some extra optimisations. - For a basic datatype like double we are not sure if it would allow the compiler to perform some extra optimisations.
- Finally it is more a question of whether you think it is worth the extra effort of marking it this way. - 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 tags: %% Cell type:markdown id:b44bb8cd-35c0-45d5-8c0e-ee80fed8d018 tags:
*** ***
Below follows our test-driver that should run through now the extension was completed Below follows our test-driver that should run through now the extension was completed
%% Cell type:code id:6fd51fae-99a1-476c-ad9f-59529b88811e tags: %% Cell type:code id:6fd51fae-99a1-476c-ad9f-59529b88811e tags:
``` C++17 ``` C++17
#include <cmath> // for using std::sqrt() below #include <cmath> // for using std::sqrt() below
int main() { int main() {
const unsigned int dim = 10; const unsigned int dim = 10;
// set up 1st vector // set up 1st vector
VectorClass myVec( dim ); VectorClass myVec( dim );
for( unsigned int idx = 1u; idx <= dim; idx++ ) { for( unsigned int idx = 1u; idx <= dim; idx++ ) {
myVec[ idx ] = static_cast<double>( dim - idx + 1u ); myVec[ idx ] = static_cast<double>( dim - idx + 1u );
} }
myVec.print( std::cout ); myVec.print( std::cout );
// set up 2nd vector // set up 2nd vector
VectorClass other( dim ); VectorClass other( dim );
for( unsigned int idx = 1u; idx <= dim; idx ++ ) { for( unsigned int idx = 1u; idx <= dim; idx ++ ) {
other[ idx ] = static_cast<double>( idx ); other[ idx ] = static_cast<double>( idx );
} }
other.print( std::cout ); other.print( std::cout );
// add the 2nd to the 1st // add the 2nd to the 1st
std::cout << "\nAdding both vectors gives: "; std::cout << "\nAdding both vectors gives: ";
myVec.add( other ); myVec.add( other );
myVec.print(); myVec.print();
// now scale second vector by 0.5 // now scale second vector by 0.5
std::cout << "\nScaling the vector: "; std::cout << "\nScaling the vector: ";
other.print(); other.print();
std::cout << "by 0.5 gives: "; std::cout << "by 0.5 gives: ";
other.scale( 0.5 ); other.scale( 0.5 );
other.print(); other.print();
std::cout << std::endl; std::cout << std::endl;
// compute the norm of the following vector // compute the norm of the following vector
VectorClass vec( 2 ); VectorClass vec( 2 );
vec[1] = 3.0; vec[1] = 3.0;
vec[2] = -4.0; vec[2] = -4.0;
double norm = vec.innerProduct( vec ); double norm = vec.innerProduct( vec );
norm = std::sqrt( norm ); norm = std::sqrt( norm );
std::cout << "Norm of vector " << vec << "is " << norm << std::endl; std::cout << "Norm of vector " << vec << "is " << norm << std::endl;
vec.print(); vec.print();
std::cout << "is " << norm << std::endl; std::cout << "is " << norm << std::endl;
std::cout << std::endl; std::cout << std::endl;
// now destructors will be called // now destructors will be called
} }
``` ```
%% Cell type:code id:9c827691-afe9-4cfb-b71d-4f01bccd09c2 tags: %% Cell type:code id:9c827691-afe9-4cfb-b71d-4f01bccd09c2 tags:
``` C++17 ``` C++17
main(); main();
``` ```
%% Output %% Output
An instance of VectorClass was generated. dim_ = 10 An instance of VectorClass was generated. dim_ = 10
(10, 9, 8, 7, 6, 5, 4, 3, 2, 1) (10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
An instance of VectorClass was generated. dim_ = 10 An instance of VectorClass was generated. dim_ = 10
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Adding both vectors gives: (11, 11, 11, 11, 11, 11, 11, 11, 11, 11) Adding both vectors gives: (11, 11, 11, 11, 11, 11, 11, 11, 11, 11)
Scaling the vector: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) Scaling the vector: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
by 0.5 gives: (0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5) by 0.5 gives: (0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5)
An instance of VectorClass was generated. dim_ = 2 An instance of VectorClass was generated. dim_ = 2
Norm of vector (3, -4) Norm of vector (3, -4)
is 5 is 5
Going to delete memory starting at address 0x55e6cfd4e580 Going to delete memory starting at address 0x55e6cfd4e580
An instance of VectorClass was destroyed and 16 bytes freed. An instance of VectorClass was destroyed and 16 bytes freed.
Going to delete memory starting at address 0x55e6d09bdf70 Going to delete memory starting at address 0x55e6d09bdf70
An instance of VectorClass was destroyed and 80 bytes freed. An instance of VectorClass was destroyed and 80 bytes freed.
Going to delete memory starting at address 0x55e6d07d8a60 Going to delete memory starting at address 0x55e6d07d8a60
An instance of VectorClass was destroyed and 80 bytes freed. An instance of VectorClass was destroyed and 80 bytes freed.
%% Cell type:markdown id:067df258-3921-4328-bd14-cec60a4a02d8 tags: %% Cell type:markdown id:067df258-3921-4328-bd14-cec60a4a02d8 tags:
*** ***
Finally, we need to answer question (3). Finally, we need to answer question (3).
* In our driver we just called ```vec.print()``` without providing an output stream as argument. How did that work? * In our driver we just called ```vec.print()``` without providing an output stream as argument. How did that work?
* At some point we change the implementation of VectorClass::print() to have a **default value** for its os argument: * At some point we change the implementation of VectorClass::print() to have a **default value** for its os argument:
**```void print( std::ostream &os = std::cout ) const```** **```void print( std::ostream &os = std::cout ) const```**
* Thus, if no argument is given, the compiler will automatically insert ```std::cout```. * Thus, if no argument is given, the compiler will automatically insert ```std::cout```.
%% Cell type:markdown id:a59f1813-b205-439d-bb91-986e51df9336 tags: %% Cell type:markdown id:a59f1813-b205-439d-bb91-986e51df9336 tags:
#### Language Overview #### Language Overview
| language | optional arguments (w/ default values) | passing via keyword | | language | optional arguments (w/ default values) | passing via keyword |
|:---------| :-------------------------------------:|:-------------------:| |:---------| :-------------------------------------:|:-------------------:|
| C | no (only via workarounds) | no | | C | no (only via workarounds) | no |
| C++ | yes | no | | C++ | yes | no |
| Fortran | yes | yes | | Fortran | yes | yes |
| Python | yes | yes | | Python | yes | yes |
Passing via keyword means, that we can set some arguments explicitely by a **name=value** pair. Passing via keyword means, that we can set some arguments explicitely by a **name=value** pair.
Python example: ```print ('comma', 'separated', 'words', sep=', ')``` Python example: ```print ('comma', 'separated', 'words', sep=', ')```
#### Optional Arguments in C++ #### Optional Arguments in C++
* In C++ there are some restrictions on the use of optional arguments. * In C++ there are some restrictions on the use of optional arguments.
* Some of these are related to the fact that *passing via keyword* is not supported. * Some of these are related to the fact that *passing via keyword* is not supported.
* Rules are: * Rules are:
- optional arguments must follow the 'regular' ones - optional arguments must follow the 'regular' ones
- if you do not supply a value for one optional argument, then you must also skip all arguments after that one - if you do not supply a value for one optional argument, then you must also skip all arguments after that one
%% Cell type:code id:aa9570b3-2a56-4b23-acaa-48c28a781870 tags: %% Cell type:code id:aa9570b3-2a56-4b23-acaa-48c28a781870 tags:
``` C++17 ``` C++17
#include <iostream> #include <iostream>
#include <string> #include <string>
void showVals( int a, int b = 2, double x = 1.0, std::string m = "go" ) { void showVals( int a, int b = 2, double x = 1.0, std::string m = "go" ) {
std::cout << "(" std::cout << "("
<< a << ", " << a << ", "
<< b << ", " << b << ", "
<< x << ", " << x << ", "
<< m << ")" << std::endl; << m << ")" << std::endl;
} }
``` ```
%% Cell type:code id:ae9ceb03-fe74-4774-9d9c-b3d6d63d6710 tags: %% Cell type:code id:ae9ceb03-fe74-4774-9d9c-b3d6d63d6710 tags:
``` C++17 ``` C++17
int main() { int main() {
showVals( 3 ); showVals( 3 );
showVals( 5, 3 ); showVals( 5, 3 );
showVals( 1, 2, 3.0 ); showVals( 1, 2, 3.0 );
showVals( 4, 5, 6, "Alte Gags" ); showVals( 4, 5, 6, "Alte Gags" );
// showVals( 3, "Polizei" ); will not compile // showVals( 3, "Polizei" ); will not compile
} }
main(); main();
``` ```
%% Output %% Output
(3, 2, 1, go) (3, 2, 1, go)
(5, 3, 1, go) (5, 3, 1, go)
(1, 2, 3, go) (1, 2, 3, go)
(4, 5, 6, Alte Gags) (4, 5, 6, Alte Gags)
%% Cell type:code id:c5eb79ba-2885-4de6-9f14-692c810222d5 tags: %% Cell type:code id:c5eb79ba-2885-4de6-9f14-692c810222d5 tags:
``` C++17 ``` C++17
``` ```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment