static_cast in C++ - c++

I was working on Circle class that is a child of Shape class and I have some tests that I have to pass that requires me to do some casting
class Shape {
friend bool operator == (const Shape& lhs, const Shape& rhs) {
return (lhs._x == rhs._x) && (lhs._y == rhs._y);}
friend istream& operator >> (istream& lhs, Shape& rhs) {
return lhs >> rhs._x >> rhs._y;}
friend ostream& operator << (ostream& lhs, const Shape& rhs) {
return lhs << rhs._x << " " << rhs._y;}
...
class Circle: public Shape {
friend bool operator == (const Circle& lhs, const Circle& rhs) {
return (lhs._radius == rhs. _radius) && static_cast<Shape>(lhs) == rhs;} // this line
...
How it's different if I did it this way? What's better?
class Circle: public Shape {
friend bool operator == (const Circle& lhs, const Circle& rhs) {
return (lhs._radius == rhs. _radius) && static_cast<const Shape&>(lhs) == rhs;}

Related

No match for operator "==" for nonmember operator overload

#include <iostream>
using namespace std;
class Test{
private: int cost{};
public:
Test(int value): cost{value}{}
int GetCost() const{return cost;}
bool operator >(const Test& rhs) const noexcept {return GetCost() > rhs.GetCost();}
bool operator>=(const Test& rhs) const noexcept {return (*this > rhs) || (*this == rhs;)}
};
bool operator==(const Test& a, const Test& b) noexcept
{
return a.GetCost() == b.GetCost();
}
int main()
{
cout<< (Test{2} >= Test{3});
return 0;
}
I get the following error for the code.
error: no match for ‘operator==’ (operand types are ‘const Test’ and ‘const Test’)
bool operator>=(const Test& rhs) const noexcept {return *this == rhs;}
What is the problem here? Is it not possible to mix member and non-member operator overloads?
You should also overload operator == in Test class.
class Test{
private:
int cost{};
public:
Test(int value): cost{value}{}
int GetCost() const{return cost;}
bool operator==(const Test& rhs) const noexcept {return GetCost() == rhs.GetCost();}
bool operator >(const Test& rhs) const noexcept {return GetCost() > rhs.GetCost();}
bool operator>=(const Test& rhs) const noexcept {return (*this > rhs) || (*this == rhs);}
};
So you can use it in your overloading and member functions like operator>=.
for more work you can do this:
bool operator==(const Test& a, const int& b) noexcept
{
return a.GetCost() == b;
}
And This:
bool operator==(const int& a, const Test& b) noexcept
{
return a == b.GetCost();
}
By doing so you can even use == as follows:
cout<< (Test{3} == 3);
cout<< (2 == Test{3});

What's the difference between using boost::equality_comparable<T> versus overriding bool operator ==?

When would I use boost::equality_comparable vs overriding T's bool operator==(T const& rhs) method?
Here's some sample code.
#include <boost/operators.hpp>
enum class AnEnum : uint64_t;
struct Base : boost::equality_comparable<Base> {
std::shared_ptr<AnEnum > units;
std::shared_ptr<int> value;
bool operator ==(Base const& rhs) {
return (*value == *rhs.value)
&& (*units == *rhs.units);
}
friend bool operator == (const Base & lhs, const Base & rhs) {
return (*lhs.value == *rhs.value)
&& (*lhs.units == *rhs.units);
};
};
I was hoping Boost would auto implement operator == but the compiler complained about a missing implementation error. Why would I want to use boost::equality_comparable when I have to implement it anyways?

std::find with two different types

I am trying to use std::find with two different types but providing the necessary boolean operators.
class FooDetails
{
public:
FooDetails(int size = 5)
: m_size(size) { /* empty */ }
bool operator<(const FooDetails& other) const { return m_size < other.m_size; }
bool operator==(const FooDetails& other) const { return m_size == other.m_size; }
private:
int m_size;
};
class Foo
{
public:
Foo(int size)
: m_details(size) { /* empty */}
bool operator==(const Foo& other) const { return m_details == other.m_details; }
bool operator==(const FooDetails& other) const {return m_details == other; }
bool operator<(const Foo& other) const { return m_details < other.m_details; }
bool operator<(const FooDetails& other) const { return m_details < other; }
FooDetails m_details;
};
bool operator==(const FooDetails& lhs, const Foo& rhs) { return lhs == rhs.m_details; }
bool operator==(const Foo& lhs, const FooDetails& rhs) {return lhs.m_details == rhs; }
bool operator<(const FooDetails& lhs, const Foo& rhs) { return lhs < rhs.m_details; }
bool operator<(const Foo& lhs, const FooDetails& rhs) { return lhs.m_details < rhs; }
int main() {
std::vector<Foo> haystack = { FooDetails(5), FooDetails(6), FooDetails(7) };
FooDetails needle(6);
std::find(haystack.begin(), haystack.end(), needle);
return 0;
}
Since std::find uses operator== I would expect this to work, since all necessary functions are provided. However this does not compile. Why is that and how do I fix it?
I know I could use std::find_if, but I assume that's a bit slower and even if it's not I'd like to know why std::find doesn't work.
I've changed your code to this:
#include <algorithm>
class FooDetails
{
public:
FooDetails(int size = 5)
: m_size(size) { /* empty */ }
bool operator<(const FooDetails& other) const { return m_size < other.m_size; }
bool operator==(const FooDetails& other) const { return m_size == other.m_size; }
private:
int m_size;
};
class Foo
{
public:
Foo(int size)
: m_details(size) { /* empty */}
FooDetails m_details;
};
bool operator==(const FooDetails& lhs, const Foo& rhs) { return lhs == rhs.m_details; }
bool operator==(const Foo& lhs, const FooDetails& rhs) {return lhs.m_details == rhs; }
bool operator<(const FooDetails& lhs, const Foo& rhs) { return lhs < rhs.m_details; }
bool operator<(const Foo& lhs, const FooDetails& rhs) { return lhs.m_details < rhs; }
int main() {
std::vector<Foo> haystack = { Foo(5), Foo(6), Foo(7) };
FooDetails needle(6);
std::find(haystack.begin(), haystack.end(), needle);
return 0;
}
And it successfully compiles. Your original version contains two errors:
You try to create std::vector<Foo> initialising it with std::initialization_list<FooDetails>.
You have provided too many comparison operators: both free versions and members of the Foo struct. So during lookup compiler complains that it doesn't know which one of them to choose. You should leave only one of them.
You have no such constructor in Foo class which constructs it from FooDetails. You need to define the following and your code will work:
Foo(const FooDetails& d) : m_details(d) {}

binary operator overloading, implicit type conversion

class my_bool {
private:
bool value;
public:
my_bool(bool value) : value(value) {}
explicit operator bool() { return value };
friend my_bool operator==(const my_bool & instance_1, const my_bool & instance_2);
friend my_bool operator&&(const my_bool & instance_1, const my_bool & instance_2);
};
void main(){
my_bool a = true;
bool b = false;
if(a == b){
// do something
}
if(a && b){
// do something
}
}
I have just created a similar topic regarding my problem over here binary operator overloading; implicit type conversion . It can be deleted I guess because it is not explicit enough about the problem I am encountering.
Why is that operator== works fine and operator&& causes ambiguities? How do I solve this problem? I can surely write down two more overloads of operator&& (bool, my_bool), (my_bool, bool). That is a messy solution though
The builtin operator&& is a context in which expressions are contextually converted to bool. Other such contexts include for example the condition of if, for, while and the conditional operator ?.
Quoting N4296, §4/4 (the latest publicly available draft before C++14):
Certain language constructs require that an expression be converted to a Boolean value. An expression e
appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the
declaration bool t(e); is well-formed, for some invented temporary variable t (8.5).
Basically, this means that there is an "impicit explicit conversion to bool" in these contexts. Or, to illustrate this further, you can think of the following two lines being one and the same:
a && b
static_cast<bool>(a) && static_cast<bool>(b)
Therefore, the compiler must consider the explicit operator bool() when doing overload resolution for operator&&, but has to ignore it when doing overload resolution for operator== (since that operator does not force a "bool context" .. you can also compare numbers, strings, ...).
The solution in your case is IMO to get rid of the operator&&(const my_bool&, const my_bool&) all together. After all, it does not produce a more meaningful behavior than what would be possible by relying on the builtin operator&&(bool, bool). Establishing a second "boolean context" just isn't something the language was designed for (see below).
If you want to keep this operator, say for some side effects, then I see these choices:
Be explicit at the call site. That is:
if (static_cast<my_bool>(a) && static_cast<my_bool>(b)) { /* ... */ }
Be explicit at the definition site: Provide additional definitions for operator&&(my_bool const &, bool), operator&&(bool, my_bool const &). These then should rule out both operator&&(my_bool const &, my_bool const &) as well as operator&&(bool, bool) because the later are less specific. Adding these definitions to your class should mitigate the issue:
friend my_bool operator&&(const my_bool & lhs, bool rhs) {
// Delegate to operator&&(const my_bool &, const my_bool &)
return lhs && my_bool(rhs);
}
friend my_bool operator&&(bool lhs, const my_bool & rhs) {
// Delegate to operator&&(const my_bool &, const my_bool &)
return my_bool(lhs) && rhs;
}
Turns out one can "establish a boolean context", using CRTP:
#include <iostream>
using namespace std;
template<typename T>
struct bool_context {
friend T operator&&(T const & lhs, bool rhs) {
return lhs && T(rhs);
}
friend T operator&&(bool lhs, T const & rhs) {
return T(lhs) && rhs;
}
friend T operator||(T const & lhs, bool rhs) {
return lhs || T(rhs);
}
friend T operator||(bool lhs, T const & rhs) {
return T(lhs) || rhs;
}
};
struct my_bool : bool_context<my_bool> {
bool value;
my_bool(bool v) : value(v) {}
explicit operator bool() { return value; };
friend my_bool operator&&(my_bool const & lhs, my_bool const & rhs) {
cout << "my_bool::operator&&" << endl;
return lhs.value && rhs.value;
}
friend my_bool operator||(my_bool const & lhs, my_bool const & rhs) {
cout << "my_bool::operator||" << endl;
return lhs.value || rhs.value;
}
};
int main(int, char**) {
my_bool a = true;
bool b = false;
cout << "a && b => "; a && b; // my_bool::operator&&
cout << "b && a => "; b && a; // my_bool::operator&&
cout << "a && a => "; a && a; // my_bool::operator&&
cout << "b && b => "; b && b; cout << endl;
cout << "a || b => "; a || b; // my_bool::operator||
cout << "b || a => "; b || a; // my_bool::operator||
cout << "a || a => "; a || a; // my_bool::operator||
cout << "b || b => "; b || b; cout << endl;
return 0;
}
(Ideone)
My first thought on this is that the arguments to the compiler's built-in operator&& are (bool, bool), so my_bool's explicit bool operator can be invoked - since you are in effect, requesting an explicit conversion.
However, I can't find any reference in the standard as to whether a variable appearing on the right hand side of && should invoke an explicit conversion to bool.
Here's the complete error output from apple clang (once the source code above is fixed):
./nod.cpp:45:10: error: use of overloaded operator '&&' is ambiguous (with operand types 'my_bool' and 'bool')
if(a && b){
~ ^ ~
./nod.cpp:33:20: note: candidate function
friend my_bool operator&&(const my_bool & instance_1, const my_bool & instance_2);
^
./nod.cpp:45:10: note: built-in candidate operator&&(_Bool, _Bool)
if(a && b){
^
1 error generated.
So how do I fix it?
Remove the user-defined && operator.
class my_bool {
private:
bool value;
public:
my_bool(bool value) : value(value) {}
explicit operator bool() { return value; }
friend my_bool operator==(const my_bool & instance_1, const my_bool & instance_2);
// friend my_bool operator&&(const my_bool & instance_1, const my_bool & instance_2);
};
int main(){
my_bool a = true;
bool b = false;
if(a == b){
// do something
}
if(a && b){
// do something
}
}
The code bellow works in the same manner for both == and &&.
The class equality is triggered only when are of the same type.
#include <stdio.h>
class my_bool {
private:
bool v{false};
public:
my_bool() : v(v) {};
operator bool (){return v;}
friend bool operator==(const my_bool a, my_bool b){
printf("operator==\n");return a.v==b;
}
friend bool operator&&(const my_bool a, my_bool b){
printf("operator&&\n");return a.v&&b;
}
};
int main(int argc, char **argv)
{ printf("Starting\n");
bool a=true,b=true;
my_bool A{},B{},R{};
a==b;a&&b;
a==A;a&&A;
A==b;A&&b;
A==B;A&&B;
}

Understanding the Next_Permutation Function in C++ for a Vector of Objects

I would like help figuring out how to use the next_permutation function on a vector of objects. I've read about people using the comp parameter, but I don't understand it. I thought the overloaded operators would fix things, but I'm still getting thrown errors. Please help me with my syntax and/or explain (with examples) the comp parameter of the next_permutation function! Thanks!
In my main file:
vector<Point> source;
//fill vector with Points, say 4 of them (1,2)(2,3)(3,4)(4,5)
next_permutation(source.begin(), source.end()); // at run I get error "Invalid operands to binary expression ('Const Point' and 'Const Point)"
My simple Point class:
class Point {
private:
double xval, yval;
public:
Point(int x = 0, int y = 0) {
xval = x;
yval = y;
}
int x() { return xval; }
int y() { return yval; }
friend bool operator<(Point& lhs, Point& rhs){
return lhs.x() < rhs.x() || (lhs.x()==rhs.x() && lhs.y()<rhs.y()) ;
}
friend bool operator==(Point& lhs, Point& rhs) {
return lhs.x()==rhs.x() && lhs.y()==rhs.y();
}
};
EDIT: This also throws the same error:
int x() const { return xval; }
int y() const { return yval; }
friend bool operator<(const Point& lhs, const Point& rhs){
return lhs.x() < rhs.x() || (lhs.x()==rhs.x() && lhs.y()<rhs.y()) ;
}
friend bool operator==(const Point& lhs, const Point& rhs) {
return lhs.x()==rhs.x() && lhs.y()==rhs.y();
}
This also throws the same error:
int x() const { return xval; }
int y() const { return yval; }
bool operator<(const Point& lhs){
return lhs.x() < x() || (lhs.x()==x() && lhs.y()<y()) ;
}
bool operator==(const Point& lhs) {
return lhs.x()==x() && lhs.y()==y();
}
Use const references and const getter functions.
int x() const { return xval; }
int y() const { return yval; }
friend bool operator<(const Point& lhs, const Point& rhs){
return lhs.x() < rhs.x() || (lhs.x()==rhs.x() && lhs.y()<rhs.y()) ;
}
friend bool operator==(const Point& lhs, const Point& rhs) {
return lhs.x()==rhs.x() && lhs.y()==rhs.y();
}
http://liveworkspace.org/code/4Drerr$0
Getter functions should be const member function, also any reason you convert from double to int?
Try:
double x() const { return xval; }
double y() const { return yval; }