class Vector{
......
.......
private:
int dim;
public:
int getDim() {
return this->dim;
}
const Vector operator+(const Vector& right){
this->getSize();
}
};
And I got compile error in this->getSize();. It is caused fact, that argument right is const. I don't know where is problem. I don't try modify right.
Presumably you have a non-const method Vector::getSize(). You need to make it const so that it can be called on const objects or via const references or pointers to const. For example:
int getSize() const;
^^^^^
Also note that it doesn't make much sense to return a const value (and would inhibit move semantics if you had them). The canonical form of an addition member operator would be
// const method: A = B + C should not modify B
Vector operator+(const Vector& right) const;
^^^^^
and the non-member
Vector operator+(const Vector& left, const Vector& right);
Related
I have been encountering an issue where I overloaded the [] operator and I am running into issues when compiling my code.
The overload defintion
double& Point::operator[](int index) { return index ? y : x; }
The class Point
`class Point {
public:
// declare constructors (3)
Point();
Point(double * arr);
//Point(double x_input, double y_input);
Point(const Point& input);
Point(const double x_input, const double y_input);
// declare overloaded operators (8 member functions)
double& operator[](int index);
Point operator+=(double num);
Point operator+=(const Point& pointee);
Point operator++(int);
Point operator++();
Point operator--(int);
Point operator--();
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
};`
The error:
error
I am not sure as to why I am encountering this issue and I was hoping if someone can shed some light as to what is happening. Thank you in advance.
I have tried adding const to the overload and its return type but to no avail.
The error message means that the operator [] is called for a constant object of the type Point but the operator is not declared as a constant member function.
Add one more overload to the operator
// declare overloaded operators (8 member functions)
double& operator[](int index);
const double& operator[](int index) const;
If the operator is defined in the global namespace outside the class definition then you need to write
const double& hlp2::Point::operator[](int index) const
{
//,,,
}
If the operator is defined in the same namespace where the class is defined then write
const double& Point::operator[](int index) const
{
//,,,
}
Shortly speaking define it as you defined the non-constant operator.
Consider a class SomeClass:
class SomeClass{
public:
// Constructors, other members
float& operator[](const unsigned i);
friend bool operator==(const SomeClass &A, const SomeClass &B);
};
Suppose this is how the == operator is overloaded for this class (not the actual implementation, but an overly simplified version):
bool operator==(const SomeClass &A, const SomeClass &B){
if (A[0] == B[0])
return true;
return false;
}
This would throw a compiler error, since the overloaded [] operator requires the instance to be non-const. However, if I change the definition of the [] operator to allow for const instances, I can no longer do assignment:
// ASSUMING: const float& operator[](const unsigned i) const;
SomeClass a;
a[0] = 0; // error, because the return value of [] is a reference to const!
I really don't want to drop the const in the parameters of the == operator, since the operands don't change within the function. What is the right way to deal with this issue?
Overload operator [] to provide both:
float& operator [](unsigned int i);
float operator [](unsigned int i) const;
For a generic T that’s not cheap to copy, use a T const& return value. The general pattern for implementing read/write operator [] is
T& operator [](index_type i);
T const& operator [](index_type i) const;
I started learning C++ not long ago and I've got an issue.
I know that a lot of similar questions has been asked about this topic.
However, I didn't deeply understand something which is why I am here.
So, my question is:
why do I need to provide 2 versions of the [] operator?
isn't the const version sufficient?
For example, I have been working on an Array class: (The last 2 operators are the relevant ones)
class Array
{
private:
int* _arrPtr;
int _len;
public:
friend ostream& operator<<(ostream& out, const Array& other);
friend istream& operator>>(istream& in, Array& other);
Array(int len = 10, int val = 0);
Array(const Array& other);
~Array();
void setArray(int len);
int* getArray() const;
void setLen(int len) { this->_len = len; }
int getLen() const { return this->_len; }
Array operator+(const Array& other) const;
Array& operator=(const Array& other);
Array operator+(int val);
int& operator[](int index) const;
int& operator[](int index);
};
can I replace the two operators
int& operator[](int index) const;
int& operator[](int index);
only with the const one?
int& operator[](int index) const;
Wouldn't it be the same??? wouldn't it be the same for any operator overloading if the there is only one const version of the operator?(under the assumption that all of the const methods do have the word 'const' at the end of their declaration)
Thank you very much!!!
Whether or not you need two overloads depends on what interface you want to provide.
If you want to be able to modify elements even in const instances of Array, then yes, the single int& operator[](int index) const; is enough. This is what std::unique_ptr does.
But if you want elements of const Arrays to be read-only, and at the same time elements of non-const Arrays to be mutable, you need two overloads. std::vector does that.
Usually the second option is preferred.
You cannot write int& operator[](int index) const;. Instead, you need to write:
const int& operator[](int index) const;
int& operator[](int index);
Why is this so? Because if something is const, you can have only const references to it or it's elements, as non-const referenes whould let you change it, which you have no right to.
If you want const references when the thing is const and non-const references in case the thing is not const, you need the overloading. If you only want const references in any case, you may get without the overloading.
I try to create a custom class used with std::set. I know I need to provide a custom comparator for it so I overloaded the operator<. But when I try to copy the set with the code set<Edge> a; set<Edge> b = a;,
I get the following error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__functional_base:63:21: Invalid operands to binary expression ('const Edge' and 'const Edge')
class Edge {
public:
Edge(int V, int W, double Weight):v(V),w(W),weight(Weight){}
int other(int vertex){ return v ? w : vertex == w;}
int v,w;
double weight;
friend std::ostream& operator<<(std::ostream& out, const Edge& e)
{
out<<e.v<<' '<<e.w<<' '<<"weight:"<<e.weight<<'\n';
return out;
}
bool operator<(const Edge& other)
{
return weight < other.weight;
}
};
Make
bool operator<(const Edge& other) const
as the comparison operator must be marked const. The keys in a std::set are const, so the operator< is invoked on a const instance, hence must be marked const.
Suppose I have the following class:
class Point{
private:
int x,y;
public:
int get_x() const {return x;}
int get_y() const {return y;}
Point() :x(0),y(0){}
Point(int x,int y):x(x),y(y){}
Point(const Point& P){
x = P.get_x();
y = P.get_y();
}
Point& operator= (const Point& P) {
x = P.get_x();
y = P.get_y();
return *this;
}
friend ostream& operator<<(ostream& os,const Point& P) {
os<<"["<<P.get_x()<<", "<<P.get_y()<<"]";
return os;
}
Point operator - (const Point &P){
return Point(x-P.get_x(),y-P.get_y());
}
friend bool operator > (const Point &A, const Point &B) {
return A.get_y()>B.get_y();
}
};
Here I used friend function. I can also use function without friend:
class Point{
...
bool operator > (const Point &B) const {
return y>B.get_y();
}
...
};
What are the differences between them in actual implementations? Also in the second method, the code won't compile without 'cont', why is that? Even after I changed the getter function into non-const function, it still won't compile without the 'const'.
As you've already noticed, comparison operator overloads can either be implemented as a member function or as a non-member function.
As a rule of thumb you should implement them as a non-member non-friend function where possible, as this increases encapsulation, and it allows (non-explicit) conversion constructors to be used on either side of the operator.
Say for instance your Point class for whatever reason had an int conversion constructor:
Point(int x);
With a non-member comparison operator you can now do the following:
Point p;
p < 3; // this will work with both a member and non-member comparison
3 < p; // this will **only** work if the comparison is a non-member function
You also seem to be confused about when to use const, again as a rule of thumb for comparison operators you should always use const wherever possible, because comparisons logically do not involve any change to the object.
As Point is a very small class you could also take it by value instead, so in order of most to least preferable your options are:
// Non-member, non-friend
bool operator>(Point const& A, Point const& B);
bool operator>(Point A, Point B);
// Non-member, friend
friend bool operator>(Point const& A, Point const& B);
friend bool operator>(Point A, Point B);
// Member
bool Point::operator>(Point const& B) const;
bool Point::operator>(Point B) const;