Reading
---------------------------------------------------------------------------------------------------------------------------------------------------------------
lets try to use the + operator to do a simple addition
File: main1.cpp
#include "cmpslib19.h"
int main()
{
string name = "Abel";
int age = 22;
cout << name + age << endl;
return 0;
}
if you look at the output from the compiler the first line is
main1.cpp: In function 'int main()':
main1.cpp:14:14: error: no match for 'operator+' (operand types are 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
cout << name + age << endl;
~~~~~^~~~~
so basically it is saying I dont know how to do the operation ( string + int )
operations for simple data types are provided but if you ask it to do something it does not know how to do you will get compilation errors
generall you CANNOT use *,-,+,==,<,> with different data types
it will then give information about how it tried seveal different things that maybe you meant to do and why they dont work.
NOTE: this is why you dont write more than a couple lines of code without trying to get it to compile. A single error can generate pages of output from the compiler
File: output1.txt
main1.cpp: In function 'int main()':
main1.cpp:14:14: error: no match for 'operator+' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
14 | cout << name + age << endl;
| ~~~~ ^ ~~~
| | |
| | int
| std::string {aka std::__cxx11::basic_string<char>}
In file included from /usr/include/c++/12/string:47,
from /usr/include/c++/12/bitset:47,
from cmpslib19.h:4,
from main1.cpp:3:
/usr/include/c++/12/bits/stl_iterator.h:630:5: note: candidate: 'template<class _Iterator> constexpr std::reverse_iterator<_Iterator> std::operator+(typename reverse_iterator<_Iterator>::difference_type, const reverse_iterator<_Iterator>&)'
630 | operator+(typename reverse_iterator<_Iterator>::difference_type __n,
| ^~~~~~~~
/usr/include/c++/12/bits/stl_iterator.h:630:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const std::reverse_iterator<_Iterator>' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/stl_iterator.h:1786:5: note: candidate: 'template<class _Iterator> constexpr std::move_iterator<_IteratorL> std::operator+(typename move_iterator<_IteratorL>::difference_type, const move_iterator<_IteratorL>&)'
1786 | operator+(typename move_iterator<_Iterator>::difference_type __n,
| ^~~~~~~~
/usr/include/c++/12/bits/stl_iterator.h:1786:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const std::move_iterator<_IteratorL>' and 'int'
14 | cout << name + age << endl;
| ^~~
In file included from /usr/include/c++/12/string:53:
/usr/include/c++/12/bits/basic_string.h:3432:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
3432 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3432:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
14 | cout << name + age << endl;
| ^~~
In file included from /usr/include/c++/12/string:54:
/usr/include/c++/12/bits/basic_string.tcc:606:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
606 | operator+(const _CharT* __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.tcc:606:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const _CharT*' and 'std::__cxx11::basic_string<char>'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.tcc:627:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
627 | operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.tcc:627:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3472:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const _CharT*)'
3472 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3472:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const _CharT*' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3489:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, _CharT)'
3489 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3489:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: deduced conflicting types for parameter '_CharT' ('char' and 'int')
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3502:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
3502 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3502:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3509:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
3509 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3509:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3516:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
3516 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3516:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3539:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
3539 | operator+(const _CharT* __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3539:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const _CharT*' and 'std::__cxx11::basic_string<char>'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3546:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
3546 | operator+(_CharT __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3546:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3553:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const _CharT*)'
3553 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3553:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: mismatched types 'const _CharT*' and 'int'
14 | cout << name + age << endl;
| ^~~
/usr/include/c++/12/bits/basic_string.h:3560:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, _CharT)'
3560 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/usr/include/c++/12/bits/basic_string.h:3560:5: note: template argument deduction/substitution failed:
main1.cpp:14:16: note: deduced conflicting types for parameter '_CharT' ('char' and 'int')
14 | cout << name + age << endl;
| ^~~
---------------------------------------------------------------------------------------------------------------------------------------------------------------
File: main2.cpp
#include "cmpslib19.h"
int main()
{
string a ="hello world";
string b = "world";
cout << a - b << endl;
return 0;
}
sometimes you cannot even do then when the data types are the same.
here we have (string - string)
and we get the error 'no match for operator-'
it does not know how to subtract one string from another and therefore it cannot compile your program.
File: output2.txt
main2.cpp: In function 'int main()':
main2.cpp:13:11: error: no match for 'operator-' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'std::string' {aka 'std::__cxx11::basic_string<char>'})
13 | cout << a - b << endl;
| ~ ^ ~
| | |
| | basic_string<[...]>
| basic_string<[...]>
In file included from /usr/include/c++/12/string:47,
from /usr/include/c++/12/bitset:47,
from cmpslib19.h:4,
from main2.cpp:3:
/usr/include/c++/12/bits/stl_iterator.h:621:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr decltype ((__y.base() - __x.base())) std::operator-(const reverse_iterator<_Iterator>&, const reverse_iterator<_IteratorR>&)'
621 | operator-(const reverse_iterator<_IteratorL>& __x,
| ^~~~~~~~
/usr/include/c++/12/bits/stl_iterator.h:621:5: note: template argument deduction/substitution failed:
main2.cpp:13:13: note: 'std::string' {aka 'std::__cxx11::basic_string<char>'} is not derived from 'const std::reverse_iterator<_Iterator>'
13 | cout << a - b << endl;
| ^
/usr/include/c++/12/bits/stl_iterator.h:1778:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr decltype ((__x.base() - __y.base())) std::operator-(const move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)'
1778 | operator-(const move_iterator<_IteratorL>& __x,
| ^~~~~~~~
/usr/include/c++/12/bits/stl_iterator.h:1778:5: note: template argument deduction/substitution failed:
main2.cpp:13:13: note: 'std::string' {aka 'std::__cxx11::basic_string<char>'} is not derived from 'const std::move_iterator<_IteratorL>'
13 | cout << a - b << endl;
| ^
---------------------------------------------------------------------------------------------------------------------------------------------------------------
File: main3.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int id;
cmps2020_student(string _name="",int _age=0)
{
name = _name;
age=_age;
}
};
int main()
{
cmps2020_student a("Angel",19);
cmps2020_student b("Amber",22);
if ( a < b)
cout << "apperantly a < b , whatever that means???" << endl;
return 0;
}
When we create our own abstract data types ( custom clases or struct )
the compiler will not know how to do ANY operations at all
it does not know how to +,-,*,/, =,==
here the compiler cannot find a match for the < operator
File: output3.txt
main3.cpp: In constructor 'cmps2020_student::cmps2020_student(std::string, int)':
main3.cpp:14:17: error: 'age' was not declared in this scope; did you mean '_age'?
14 | age=_age;
| ^~~
| _age
main3.cpp: In function 'int main()':
main3.cpp:25:11: error: no match for 'operator<' (operand types are 'cmps2020_student' and 'cmps2020_student')
25 | if ( a < b)
| ~ ^ ~
| | |
| | cmps2020_student
| cmps2020_student
---------------------------------------------------------------------------------------------------------------------------------------------------------------
File: main4.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int age;
cmps2020_student(string _name="",int _age=0)
{
name = _name;
age=_age;
}
bool operator < (const cmps2020_student & rhs)
{
// so lets write a less than operator , we will need something to compare them by
// lets use the age value
if (this->age < rhs.age )
return true;
else
return false;
}
};
int main()
{
cmps2020_student a("Angel",19);
cmps2020_student b("Amber",22);
if ( a < b)
cout << "apperantly a < b , whatever that means???" << endl;
if (a == b)
cout << "apperantly a == b , whatever that means???" << endl;
return 0;
}
Here we have added an overloaded operator for the < operator
the compiler no longer stops here as it can now find some logic to do the < comparision
It will however stop when we try to use the == operator
so lets add that now
File: output4.txt
main4.cpp: In function 'int main()':
main4.cpp:37:10: error: no match for 'operator==' (operand types are 'cmps2020_student' and 'cmps2020_student')
37 | if (a == b)
| ~ ^~ ~
| | |
| | cmps2020_student
| cmps2020_student
---------------------------------------------------------------------------------------------------------------------------------------------------------------
File: main5.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
int age;
cmps2020_student(string _name="",int _age=0)
{
name = _name;
age=_age;
}
bool operator < (const cmps2020_student & lhs)
{
// so lets write a less than operator , we will need something to compare them by
// lets use the age value
// Given how it is called below if (a < b)
// age is a.age
// this->age is a.age
// name is a.name
// this->name is a.name
// lhs.name is b.name
// lhs.age is b.age
if (this->age < lhs.age )
return true;
else
return false;
}
bool operator == (const cmps2020_student & lhs)
{
// so lets write an equality operator , we will need something to compare them by
// lets use the age and name
// Given how it is called below if (a == b)
// age is a.age
// this->age is a.age
// name is a.name
// this->name is a.name
// lhs.name is b.name
// lhs.age is b.age
if ( (this->age < lhs.age) && (this->name == lhs.name) )
return true;
else
return false;
}
};
int main()
{
cmps2020_student a("Angel",19);
cmps2020_student b("Amber",22);
if ( a < b)
cout << "apperantly a < b , whatever that means???" << endl;
if (a == b)
cout << "apperantly a == b , whatever that means???" << endl;
return 0;
}
Here we have added an overloaded operator for the equality operator
as well so our code will compiler and run properly
---------------------------------------------------------------------------------------------------------------------------------------------------------------
The format of the operator overloading is quite similar to a standard function
it has a return type , name and parameters.
lets simplify our class quite a bit and look at how it works
File: main6.cpp
#include "cmpslib19.h"
class cmps2020_student
{
public:
string name;
cmps2020_student(string _name="") {name = _name;}
bool operator == (const cmps2020_student & rhs)
{
// given how it is called below
// this pointer is a since it calls the function on the object a on the lhs (left hand side ) of the ==
// b is on the rhs (right hand side) of the == operator and it gets passed in as rhs
// name is a.name
// this->name is a.name
if ( this->name == rhs.name )
return true;
else
return false;
}
};
int main()
{
cmps2020_student a("Angel");
cmps2020_student b("Amber");
// the == operator is supposed to compare what it on its left hand side with what is the on the right hand side
// technically both a and b have the operator function but it will call it on a (lhs) and pass in b (rhs) as a parameter
if (a == b) // imagine it is calling a.operator==( b ); //
cout << "apperantly a == b , whatever that means???" << endl;
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------
there are several other demo programs to examine as well as the CFraction class we have used a few times in this class, it has a dozen overloaded operators