possible implementations of casting in c++ - c++

I have this snippet of the code in my header:
class A {
private:
int player;
public:
A(int initPlayer = 0);
A(const A&);
A& operator=(const A&);
~A();
void foo() const;
friend int operator==(const A& i, const A& member) const;
};
implementation of the operator==
int operator==(const A& i, const A& member) const{
if(i.player == member.player){
return 1;
}
return 0;
}
and I need casting for this part of my code:
i - is some int, which my function receives
A *pa1 = new A(a2);
assert(i == *pa1);
I receive an error non-member function, How can I fix it? thanks in advance

Your error is nothing to do with casting or user-defined conversions.
You can't have a const qualification on a function that isn't a member function so this:
int operator==(const A& i, const A& member) const;
should be this:
int operator==(const A& i, const A& member);

Remove the const qualifier from the friend function. Friend functions are not member functions hence the const qualifier is meaningless.

There are two solutions:
Make operator==() a member function, not a friend:
Interface:
class A {
private:
int player;
public:
A(int initPlayer = 0);
A(const A&);
A& operator=(const A&);
~A();
void foo() const;
int operator==(const A& rhv) const;
};
Implementation:
int A::operator==(const A& rhv) const
{
return this->player == rhv.player;
}
If you really want operator==() as a friend function, just remove the const qualifier, as mentioned in the other posts.

Related

Adding unrelated operator == renderers spaceship operator(<=>) non-functional

In this code example, it seems that adding unreleated operator== (on a different type) renders the shaceship opreator not functional. This is tested in VS2019. Is it a compiler bug, or some weird behaviour?
class A
{
public:
int x;
};
class B
{
public:
constexpr std::strong_ordering operator<=>(const B& other) const = default;
constexpr bool operator==(const A& other) const { return this->x == other.x; } // remove this so it can compile
int x;
};
class C
{
public:
constexpr operator bool() const { return b1 == b2; }
B b1, b2;
};
The error I get is in the usage of the operator in the class B is:
binary '==': no operator found which takes a left-hand operand of type 'const B' (or there is no acceptable conversion)
Referring to cppreference's page on how defaulted comparison operators work, let's examine what's happening.
For the first case, with no user-declared operator==:
class B
{
public:
constexpr std::strong_ordering operator<=>(const B& other) const = default;
int x;
};
The following applies:
If operator<=> is defaulted and operator== is not declared at all, then operator== is implicitly defaulted.
The default signature for operator== is bool operator==(const B& other) const. All well and good.
In your second version, you do declare an operator==. This means you do not get the defaulted operator== as a side-effect of defaulting operator<=>.
class B
{
public:
constexpr std::strong_ordering operator<=>(const B& other) const = default;
constexpr bool operator==(const A& other) const { return this->x == other.x; }
// No additional `operator==` will be generated aside from the above
int x;
};
The problem is that the operator== you declared takes a const A& as the right hand side, instead of a const B&. So you cannot use this operator== to perform a check of the form b1 == b2.
If you want to have both the operator==(const A&) const overload and the default operator==(const B&) const overload, you can explicitly request that the latter be defaulted, like so:
class B
{
public:
constexpr std::strong_ordering operator<=>(const B& other) const = default;
constexpr bool operator==(const B& other) const = default;
// Explicitly request default operator== as well as default operator<=>
constexpr bool operator==(const A& other) const { return this->x == other.x; }
int x;
};

std:hash with access to private members of a class

I would like to hash a class that has two private members e.g.:
foo.h
class Foo {
private:
std::string a;
std::string b;
public:
Foo (std::string a, std::string b);
bool operator==(const Foo& other) const;
bool operator!=(const Foo& other) const;
std::size_t operator()(const Foo& ) const;
};
namespace std {
template <> struct hash<Foo> {
std::size_t operator()(const Foo& cp) const;
};
}
foo.cpp
Foo::Foo (std::string _a, std::string _b) {
this->a = _a;
this->b = _b;
}
bool Foo::operator== (const Foo& other) const {
return this->a == other.a && this->b == other.b;
}
bool Foo::operator!= (const Foo& other) const {
return !operator==(other);
}
std::size_t std::hash<Foo>::operator()(Foo const& foo) const {
std::string f = foo.a; // << This wont compile!
return 1;
}
In C++ how is hashing of Foo typically done when that final hash function doesn't have access to the private member of foo.
Feel free to include boost or abseil in your answer.
What you can do is declare std::hash<Foo> as a friend of Foo:
class Foo {
private:
std::string a;
std::string b;
public:
Foo(std::string a, std::string b);
bool operator==(const Foo& other) const;
bool operator!=(const Foo& other) const;
std::size_t operator()(const Foo&) const;
friend std::hash<Foo>;
};

C++ Undefined reference to base class functions at link time (--not-- vtables, constructors, templates, or pure virtual functions)

I'm working on a project attempting to implement a stand-alone base class (A) that can be extended by later classes (such as B and C). I want to be able to use them all independently, hence no pure virtual functions, and I want only one copy of each class in any derived classes (hence the virtuals to avoid the Dreaded Diamond). Some classes, like D, need to combine all the previously extended classes, retaining all their functions while implementing additional ones.
For added fun I'm (stuck) using C++03, gcc 4.4.6, and make 3.81.
Everything compiles fine, but I keep getting 'undefined reference to '[base class function]' at link whenever and however I attempt to use the base class functions in the derived class.
All the answers I've been able to find so far are about incorrectly implementing pure virtual functions, trying to monkey with constructors, or have failed to implement all the members of a class (hence the vtable errors). I'm not (knowingly) doing or intending any of these things.
It would be cool if these were implemented as templates, but it's unfortunately not possible due to the complexity. I can't post the actual code, but I've mocked up examples resembling the basic structure and behavior:
Header file declaring the classes:
#ifndef CODE_H
#define CODE_H
class A
{
protected:
int a_;
int b_;
int c_;
public:
explicit A() :
a_(0), b_(0), c_(0) {}
A(const int X, const int Y, const int Z) :
a_(X), b_(Y), c_(Z) {}
A(const A& X) :
a_(X.A()), b_(X.B()), c_(X.C()) {}
int doA1(const A& X) const;
int doA2() const;
A getA() const;
A& operator=(const A& X);
const int& A() const {return a_;}
const int& B() const {return b_;}
const int& C() const {return c_;}
//One for each operator but not shown for brevity
A operator+(const A& X) const;
void operator+=(const A& X);
A operator+(const int X) const;
void operator+=(const int X);
};
class B : public virtual A
{
protected:
int d_;
public:
explicit B() :
A(), d_(0) {}
B(const int D, A X) :
A(X), d_(D) {}
B(const int D) :
d_(D) {}
int doB1(const B& X) const;
B getB() const;
B& operator=(const B& X);
const int& D() const {return d_;}
//One for each operator but not shown for brevity.
//int d_ doesn't need to be modified by the operators, so it's ignored in their implementation.
B operator+(const B& X) const {return B(d_, (A::operator+(X.getA())));}
void operator+=(const B& X) {A::operator+=(X.getA());}
B operator+(const int X) const; {return B(d_, (A::operator+(X)));}
void operator+=(const int X) {A::operator+(X);}
};
class C : public virtual A
{
protected:
int e_;
int f_;
int g_;
public:
explicit C() :
A(), e_(0), f_(0), g_(0) {}
C(const int U, const int V, const int W,
const int X, const int Y, const int Z) :
A(U, V, W), e_(X), f_(Y), g_(Z) {}
C(const A& W,
const int X, const int Y, const int Z) :
A(W), e_(X), f_(Y), g_(Z) {}
C(const C& X) :
C(X.A(), X.B(), X.C()), e_(X.E()), f_(X.F()), g_(X.G()) {}
int doC1(const C& X) const;
C getC() const;
C& operator=(const C& X);
const int& E() const {return e_;}
const int& F() const {return f_;}
const int& G() const {return g_;}
//One for each operator but not shown for brevity
C operator+(const C& X) const;
void operator+=(const C& X);
C operator+(const int X) const;
void operator+=(const int X);
};
class D : public virtual B, public virtual C
{
public:
explicit D() :
B(), C() {}
D(const int D, C Y) :
B(D), C(Y) {}
int doD1(const D& X) const;
int doD2() const;
D getD() const;
D& operator=(const D& X);
//One for each operator but not shown for brevity.
D operator+(const D& X) const {return D(d_, (C::operator+(X.getC())));}
void operator+=(const D& X) {C::operator+=(X.getC());}
D operator+(const int X) const; {return D(d_, (C::operator+(X)));}
void operator+=(const int X) {C::operator+(X);}
};
#endif
File implementing A:
#include header.h
int A::doA1(const A& X) const
{
int doStuff;
//does stuff.
return doStuff;
}
int A::doA2() const
{
int doStuff2;
//does stuff.
return doStuff2;
}
A A::getA() const
{
A out(a_, b_, c_);
return out;
}
A& A::operator=(const A& X)
{
if (this != &X)
{
a_ = X.a_;
b_ = X.b_;
c_ = X.c_;
}
return *this;
}
//One for each operator but not shown for brevity
A A::operator+(const A& X) const
{
return A(a_ + X.a_, b_ + X.b_, c_ + X.c_);
}
void A::operator+=(const A& X)
{
a_ += X.a_;
b_ += X.b_;
c_ += X.c_;
}
A A::operator+(const int X) const
{
return A(a_ + X, b_ + X, c_ + X);
}
void A::operator+=(const int X)
{
a_ += X;
b_ += X;
c_ += X;
}
File implementing B:
#include header.h
int B::doB1(const B& X) const
{
//Linker complains on both doA1 and getA, even if I qualify them or remove all the qualifiers
return (A::doA1(X.getA()));
}
B B::getB() const
{
//Also complains here, with or without qualifiers.
B out(d_, A::getA());
return out;
}
B& B::operator=(const B& X)
{
if (this != &X)
{
//Also here, for presumably the same reason.
A::operator=(D.getA());
d_ = X.d_;
}
return *this;
}
I can provide mockups for C and D as well, though they follow the same basic pattern as A and B.
Based on the answers I've seen so far I should, at most, only need to add the base class qualifier to the functions to avoid any accidental name hiding, but that doesn't appear to work. Also strangely: instantiated objects can't seem to find their public functions (like in doB1). Am I just a moron missing something obvious (which I wouldn't be surprised coming from a C background)?
You are defining global functions instead of class methods.
In class A
int doA1(const A& X) const;
int doA2() const;
Implemetation
int A::doA1(const A& X) const
int doA2() const
Thera is no A:: in second case.

Overload operator for set of sets

I just build a mini program to understand how this will work because i need this for something a bit more difficult but i can't make this work.
I think i need to define operator overload but i dont know how because they are two objects of set<set<a>>
If you compile you will see a big error where it notice that he can't compare myset == myset2 and i think it will say same for operator != and =
#include <set>
using namespace std;
class a{
private:
int a_;
public:
int get_a() const{ return a_; }
void set_a(int aux){ a_=aux;}
bool operator < (const a& t) const{
return this->get_a() < t.get_a();
}
};
class b{
private:
set<set<a> > b_;
public:
void set_(set<a> aux){ b_.insert(aux); }
//Overload operators?
};
int main(){
b myset;
b myset2;
set<a> subset1;
set<a> subset2;
a myint;
myint.set_a(1);
subset1.insert(myint);
myint.set_a(2);
subset1.insert(myint);
myint.set_a(3);
subset1.insert(myint);
myint.set_a(5);
subset2.insert(myint);
myint.set_a(6);
subset2.insert(myint);
myint.set_a(7);
subset2.insert(myint);
myset.set_(subset1);
myset.set_(subset2);
myset2.set_(subset1);
myset2.set_(subset2);
if(myset == myset2){
cout << "They are equal" << endl;
}
if(myset != myset2){
cout << "They are different" << endl;
}
b myset3;
myset3 = myset2; //Copy one into other
}
In order for your code to work you need to specify following operators (note: they are not created by default)
class a{
private:
int a_;
public:
int get_a() const{ return a_; }
void set_a(int aux){ a_=aux;}
/* needed for set insertion */
bool operator < (const a& other) const {
return this->get_a() < other.get_a();
}
/* needed for set comparison */
bool operator == (const a& other) const {
return this->get_a() == other.get_a();
}
};
class b{
private:
set<set<a> > b_;
public:
void set_(set<a> aux){ b_.insert(aux); }
/* needed, because myset == myset2 is called later in the code */
bool operator == (const b& other) const {
return this->b_ == other.b_;
}
/* needed, because myset != myset2 is called later in the code */
bool operator != (const b& other) const {
return !(*this == other);
}
};
You should also take a look at http://en.cppreference.com/w/cpp/container/set and see what other operators std::set uses internally on its elements.
No operator (except for the default operator=(const T&) and operator=(T&&)) is generated by the compiler by default. You should define them explicitly:
class b{
private:
set<set<a> > b_;
public:
void set_(set<a> aux){ b_.insert(aux); }
//Overload operators?
bool operator==(const b& other) const {
return b_ == other.b_;
}
bool operator!=(const b& other) const {
return b_ != other.b_;
}
};
However, this only does not solve the case. Although comparison operators are already defined for std::set<T>, they only work if there are operators for T. So, in this case, you have to define operator== and operator!= for your a class in the same manner as I showed you with b class.

conversions in C++

I have this snippet of the code:
header
class A {
private:
int player;
public:
A(int initPlayer = 0);
A(const A&);
A& operator=(const A&);
~A();
void foo() const;
friend A& operator=(A& i, const A& member);
};
operator=
A& operator=(A& i, const A& member){
i(member.player);
return i;
}
and I have row in my code:
i = *pa1;
A *pa1 = new A(a2);
at the beginning i was int
how can I fix it, thanks in advance
I have an error must be non-static function
The assignment operator for a class must be a member function, not a friend.
A& operator=( const A& member){
this->player = member.player);
return *this;
}
If you want to convert an A class object to an integer, provide a named conversion function such as ToInt().
As with all your questions, this could easily have been answered by reading a C++ text book. This is the last of such questions from you I will be answering.