C++ Equals Operator - c++

I have the following equals operator:
bool operator==(const Duration& x, const Duration& y){
return ( x.hrs == y.hrs, x.mins == y.mins, x.secs == y.secs );
}
I have also tried:
bool operator==(const Duration& x, const Duration& y){
return ( (x.hrs == y.hrs) && (x.mins == y.mins) && (x.secs == y.secs) );
}
In my main method I have:
//Arbitrary Durations - Testing
Duration dTest0 (01,45,12);
Duration dTest1 (01,35,45);
Duration dTest2 (01,35,45);
Duration dTest3 (01,25,05);
if ( dTest0 == dTest1 ){
cout<< "broken" << endl;
}
else{
cout<< "working" << endl;
}
My program keeps outputting "broken" which suggests that dTest0 and dTest1 are infact equal... Where am I going wrong?
Additional: If I use x.getHours == y.getHours... It puts a red line under the "." and says: 'Error: a pointer to a bound function may only be used to call the function`.
Any advice would be appreciated. Thanks.

The first implementation will only return true if x.secs == y.secs. The results of the first two comparisons will be discarded. The , operator evaluates to the value of its second operand, which in this case boils down to just x.secs == y.secs.
The second one, however, is correct. If it is not working, then you must be setting the values of hrs, mins, and secs incorrectly in the constructor of Duration.
The problem that you have with getHours is that you need to call it. It is a member function after all. So do x.getHours() instead of x.getHours.

The first one is wrong. , does not work that way.
The second one is correct, assuming Duration is reasonable.
You may have a bug in your Duration constructor. I'd even think it is likely.

Related

Why I cannot assign values to a variable with if and if else statements?

#include <iostream>
using namespace std;
void main()
{
int leftover;
int gold = 3900;//satisfies the if else statement
if( gold>=4100){//successfully build item
leftover = gold-4100;
}
else if(4100>gold>=3500){
leftover = gold-3500;
}
cout << leftover << endl;
system("pause");
}
This code doesn't work, it will show that leftover is used without being initialized. But when I changed the value of gold(etc 4200) to satisfy the if statement, it will work, displaying the remainder after gold has been deducted from 4100. I am just learning c++ in school so I am not familiar with if and if else statements yet so many thanks for telling me what went wrong!
4100>gold>=3500 doesn't do what you think. It's evaluated as (4100>gold) >= 3500, which depending on the value of gold can be 0 >= 3500 or 1>3500. Look up operator precedence.
You probably want
(4100>gold) && (gold>=3500)
If you don't initialize the value and the if statements fail, then you cout null
You have two suggestions here:
FIRST:
int leftover = -1; //Initialize the value
SECOND:
else { leftover = 0; } //Default the value if the if case fails
Yea I made a VERY careless mistake, the only problem is 4100>gold>3500 will never get evaluated.
Thanks to all who answered and pointed out to use AND gate instead of shared operands!

A bool function doesn't work in stable_sort function

The shipwreck;
Input a number, than a vector of type Passenger passengers(number), where Passenger is a struct that consists of string name and string status;
the problem is to sort the passengers who was on the ship by the next priority:
a) first who leaves the ship is rat, than the ship leaves whoman or a child, than the ship leaves a man, the last one who leaves the ship is the captain;
b) it is necessary to write a bool function which we will use in function stable_sort to sort the vector of passengers;
I tried this:
int Priority1(Passenger pas)
{
if(pas.status == "rat")
return 3;
if(pas.status == "woman" || pas.status == "child")
return 2;
if(pas.status == "man")
return 1;
if(pas.status == "captain")
return 0;
}
bool Priority(Passenger pas1, Passenger pas2)
{
return Priority1(pas1) > Priority1(pas2);
}
If your trying to implement an ordering function for one of the
standard library functions, your function is trivially wrong,
because it returns true if both passengers are rats. To
establish a proper ordering function, comparing any two entries
in the same equivalence class must return false.
Further down... what happens if both passengers are men? None
of your if are true, and you fall off the end, resulting in
undefined behavior. (FWIW: it's generally a bad practice to
throw return around right and left in the function. One
single return, as the last line in the function, and outside of
any control structure is a good general rule.)
Anyway, the approach I would take would be to to map both values
to an integral priority, and then return Priority(pas1) < Priority(pas2);. Much simpler, and guaranteed not to miss
any cases.
if(pas1.status == "man" && pas2.status != "woman" && pas2.status == "child" && pas2.status != "rat")
I think the third condition pas2.status == "child", should be pas2.status != "child"
Also, there is no default return statement in the function.

boolean operations overloading inside classes in c++ and if statements for dates inside a class

I'm using this code in my previous question:
Adding the year implementation in c++ using a class
I want to use an if statement to check for dates in a way that if the day was 31 it gets back to 0 and the month gets incremented by one. I even tried to write another method and use it inside of the + operation but this failed as well because I'm incrementing the day in the return function inside of the operation declaration. As a result, it will need to be incremented before checking for the conditions first ! but what if the number was initially 31? there is no month that has 32 days !
I tried to use it but because of my implementation it didn't work as it should
My other question is that I'm trying to use a Boolean reference check with the operation == as well
This is what I've done so far :
bool operator==(const Date&) const;
bool Date::operator==(const Date& date) const
{
if (day == date.day && monthnum == date.monthnum && year == date.year)
return true;
else return false;
}
but for some reason when I try to test it in the main by saying for example, date1==date2, it doesn't compile !
am I writing it wrong ?
"no operation == matches these operands"
this is the error I get when I try to compile the code
I want to use an if statement to check for dates in a way that if the day was 31 it gets back to 0 and the month gets incremented by one.
This is as simple to implement as:
if (day == 31) {
day = 0;
monthnum++;
}
I try to test it in the main by saying for example, date1==date2, it doesn't compile ! am I writing it wrong ?
Yeah well, you are declaring a free function operator==, while what you want is a member function. Inside Date do:
class Date {
public:
// ...
bool operator==(const Date&) const;
// ...
};
You can also use a free function, to be honest, but that would require more changes and it generally is the same. Just in case you want to use it here's how:
bool operator==(const Date& lhs, const Date& rhs) {
return (lhs.day == rhs.day && lhs.monthnum == rhs.monthnum && lhs.year == rhs.year);
}
(I've removed the redundant if-else pair).
The compiler states that "no operation == matches these operands". I simply have this code in my main: cout << date1 == date2;
Yes, you should do this instead:
cout << (date1 == date2);
otherwise what the compiler reads is this:
(cout << date1) == date2;

Recursive Function Error

Im trying to create a recursive function that contains a vector of numbers and has a key, which is the number we are looking for in the vector.
Each time the key is found the function should display a count for how many times the key appears in the vector.
For some reason my recursive function is only returning the number 1 (disregard the 10 I was just testing something)
Here's my code:
int recursive_count(const vector<int>& vec, int key, size_t start){
if (start == vec.size())
return true;
return (vec[start] == key? 23 : key)
&& recursive_count(vec, key, (start+1));
}
int main() {
vector <int> coco;
for (int i = 0; i<10; i++) {
coco.push_back(i);
}
cout << coco.size() << endl;
int j = 6;
cout << recursive_count(coco, j, 0) << endl;
}
Not sure what you are trying to do, but as is - your function will return false (0) if and only if the input key is 0 and it is in the vector. Otherwise it will return 1.
This is because you are basically doing boolean AND operation. The operands are true for all values that are not 0, and the only way to get a 0 - is if it is in the vector - and the key is 0.
So, unless you get a false (0) along the way, the answer to the boolean formula is true, which provides the 1.
EDIT:
If you are trying to do count how many times the key is in vec - do the same thing you did in iterative approach:
Start from 0 (make stop condition return 0; instead of return true;)
Increase by 1 whenever the key is found instead of using operator&&, use the operator+.
(I did not give a direct full answer because it seems like HW, try to follow these hints, and ask if you have more questions).
To me it seems that a recursive function for that is nonsense, but anyway...
Think about the recursion concepts.
What is the break condition? That the current character being checked is not in the string anymore. You got that right.
But the recursion case is wrong. You return some kind of bool (what's with the 23 by the way?
The one recursion round needs to return 1 if the current element equals key, and 0 otherwise.
Then we only need to add up the recursion results, and we're there!
Here's the code
int recursive_count(const vector<int>& vec, int key, size_t start) {
if (start >= vec.size()) {
return 0;
} else {
return
((vec[start] == key) ? 1 : 0) +
recursive_count(vec, key, start+1);
}
}
Since this is even tail-recursion, good compilers will remove the recursion for you by the way, and turn it into its iterative counterpart...
Your recursive_count function always evaluates to a bool
You are either explicitly returning true
if (start == vec.size())
return true;
or returning a boolean compare
return (vec[start] == key? 23 : key) // this term gets evaluated
&& // the term above and below get 'anded', which returns true or false.
recursive_count(vec, key, (start+1)) // this term gets evaluated
It then gets cast to your return type ( int ), meaning you will only ever get 0 or 1 returned.
As per integral promotion rules on cppreference.com
The type bool can be converted to int with the value false becoming
​0​ and true becoming 1.
With,
if (start == vec.size())
return true;
your function with return type int returns 1

Is this the right way to use recursion?

Given strings s and t compute recursively, if t is contained in s return true.
Example: bool find("Names Richard", "Richard") == true;
I have written the code below, but I'm not sure if its the right way to use recursion in C++; I just learned recursion today in class.
#include <iostream>
using namespace std;
bool find(string s, string t)
{
if (s.empty() || t.empty())
return false;
int find = static_cast<int>(s.find(t));
if (find > 0)
return true;
}
int main()
{
bool b = find("Mississippi", "sip");
string s;
if (b == 1) s = "true";
else
s = "false";
cout << s;
}
If anyone find an error in my code, please tell me so I can fix it or where I can learn/read more about this topic. I need to get ready for a test on recursion on this Wednesday.
The question has changed since I wrote my answer.
My comments are on the code that looked like this (and could recurse)...
#include <iostream>
using namespace std;
bool find(string s, string t)
{
if (s.empty() || t.empty())
return false;
string start = s.substr(0, 2);
if (start == t && find(s.substr(3), t));
return true;
}
int main()
{
bool b = find("Mississippi", "sip");
string s;
if (b == 1) s = "true";
else
s = "false";
cout << s;
}
Watch out for this:
if (start == t && find(s.substr(3), t));
return true;
This does not do what you think it does.
The ; at the end of the if-statement leaves an empty body. Your find() function will return true regardless of the outcome of that test.
I recommend you turn up the warning levels on your compiler to catch this kind of issue before you have to debug it.
As an aside, I find using braces around every code-block, even one-line blocks, helps me avoid this kind of mistake.
There are other errors in your code, too. Removing the magic numbers 2 and 3 from find() will encourage you to think about what they represent and point you on the right path.
How would you expect start == t && find(s.substr(3), t) to work? If you can express an algorithm in plain English (or your native tongue), you have a much higher chance of being able to express it in C++.
Additionally, I recommend adding test cases that should return false (such as find("satsuma", "onion")) to ensure that your code works as well as calls that should return true.
The last piece of advice is stylistic, laying your code out like this will make the boolean expression that you are testing more obvious without resorting to a temporary and comparing to 1:
int main()
{
std::string s;
if (find("Mississippi", "sip"))
{
s = "true";
}
else
{
s = "false";
}
std::cout << s << std::endl;
}
Good luck with your class!
Your recursive function needs 2 things:
Definite conditions of failure and success (may be more than 1)
a call of itself to process a simpler version of the problem (getting closer to the answer).
Here's a quick analysis:
bool find(string s, string t)
{
if (s.empty() || t.empty()) //definite condition of failure. Good
return false;
string start = s.substr(0, 2);
if (start == t && find(s.substr(3), t)); //mixed up definition of success and recursive call
return true;
}
Try this instead:
bool find(string s, string t)
{
if (s.empty() || t.empty()) //definite condition of failure. Done!
return false;
string start = s.substr(0, 2);
if (start == t) //definite condition of success. Done!
return true;
else
return find(s.substr(3), t) //simply the problem and return whatever it finds
}
You're on the right lines - so long as the function calls itself you can say that it's recursive - but even the most simple testing should tell you that your code doesn't work correctly. Change "sip" to "sipx", for example, and it still outputs true. Have you compiled and run this program? Have you tested it with various different inputs?
You are not using recursion. Using std::string::find in your function feels like cheating (this will most likely not earn points).
The only reasonable interpretation of the task is: Check if t is an infix of s without using loops or string functions.
Let's look at the trivial case: Epsilon (the empty word) is an infix of ever word, so if t.empty() holds, you must return true.
Otherwise you have two choices to make:
t might be a prefix of s which is simple to check using recursion; simply check if the first character of t equals the first character of s and call isPrefix with the remainder of the strings. If this returns true, you return true.
Otherwise you pop the first character of s (and not of t) and proceed recursively (calling find this time).
If you follow this recipe (which btw. is easier to implement with char const* than with std::string if you ask me) you get a recursive function that only uses conditionals and no library support.
Note: this is not at all the most efficient implementation, but you didn't ask for efficiency but for a recursive function.