I'm trying to overload the Array subscript operator on a Matrix, however I'm getting an error that I can't understand. The CMazeSquare && operator[] (const tuple &other); is meant to access the CMazeSquare grid** which a matrix of CMazeSquares. I would like to be able to access the CMazeSquare object just by saying grid[someTuple]
CMaze.h:61:17: error: expected unqualified-id before ‘&&’ token
CMazeSquare && operator [] (const tuple &other);
^
I can't for the life of me understand what is wrong here. Please help.
#ifndef CMAZE_H
#define CMAZE_H
struct tuple
{
short x;
short y;
tuple();
tuple(const tuple &other);
tuple(short X, short Y);
tuple operator + (const tuple &other);
};
class CMaze
{
public:
private:
struct CMazeSquare
{
CMazeSquare ();
void Display (ostream & outs);
sType what;
bool vistited;
};
CMazeSquare ** grid;
CMazeSquare && operator [] (const tuple &other); //<- This is the problem
};
#endif
I'm thinking the implementation of the operator would look something like this:
//in CMaze.cpp
CMaze::CMazeSquare && CMaze::operator [](tuple &other)
{
return this[other.x][other.y];
}
This is how operator[] is usually overloaded:
CMazeSquare& operator[] (const tuple &other)
{
return grid[other.x][other.y];
}
const CMazeSquare& operator[] const (const tuple &other)
{
return grid[other.x][other.y];
}
There a few problems with your code:
First, the definition doesn't match the declaration:
CMazeSquare && operator [] (const tuple &other);
vs
CMaze::CMazeSquare && CMaze::operator [](tuple &other)
Note the const missing in the definition parameters
Then you can't say this[...]. It doesn't do what you think it does.
Lastly why are you trying to return an rvalue reference? You need 2 overloads one for const returning a const lvalue reference and one for mutable returning a mutable reference.
the error you got I suppose is because you don't compile in C++11 and the compiler doesn't understand &&.
Related
I'm trying to find a SnekNode object in an std::vector using
auto it = std::find(snek_node_container.begin(), snek_node_container.end(), snek_node);
but it raises a compiler error:
Error C2676 binary '==': 'SnekNode' does not define this operator or a
conversion to a type acceptable to the predefined operator
which points to the xutility file as source which is not very helpful. When I try to define a == function in the class such as:
SnekNode operator== (const SnekNode& rhs) {
return (*this == rhs);
}
I get another compilation error:
C2451 conditional expression of type "SnekNode" is illegal
which also points to the xutility file which again, sadly doesn't help me. What am I doing wrong here? Thanks in advance!
operator== should return bool.
Also, you need to compare the members individually. In your code you just call operator== again, causing infinite recursion.
What you can do is use the operator== in operator!= to save typing, e.g.:
struct SnekNode
{
bool operator== (const SnekNode& rhs) const {
return a == rhs.a &&
b == rhs.b &&
c == rhs.c;
}
bool operator!= (const SnekNode& rhs) const {
return !(*this == rhs);
}
// auto operator<=>(const SnekNode&) const = default; // C++20
int a{0};
int b{1};
int c{2};
};
With C++20 you can use default comparisons (spaceship operator).
Live demo
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 have a struct defined like this:
struct IFSFunc {
int a;
bool operator<(const IFSFunc& other) {
return a < other.a;
}
};
Since IFSfunc is a struct, access modifier for the operator< should be public.
I also have this code:
#include <algorithm>
std::vector<std::pair<double, IFSFunc>> ifsFuncs;
// fill the vector with various data
std::sort(ifsFuncs.begin(), ifsFuncs.end());
I need to sort ifsFuncs based on the first double in the pair. I don't care about IFSFunc structure, if the double is the same.
However, for std::sort to work, which is defined like this:
template <class _Ty1, class _Ty2>
_NODISCARD constexpr bool operator<(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) {
return _Left.first < _Right.first || (!(_Right.first < _Left.first) && _Left.second < _Right.second);
}
I have to override the less than operator for the second in this case IFSfunc, which I did. However, trying to compile this code gives me the following error:
Error C2678 binary '<': no operator found which takes a left-hand operand of type 'const _Ty2' (or there is no acceptable conversion)
Why?
You need to define that operator as a const member function.
Also, don't just return true for a comparison. That can result in infinite looping.
I just figure it out. The overloaded function signature was wrong, this is what I need:
struct IFSFunc {
int a;
bool operator<(const IFSFunc& other) const {
return a < other.a;
}
};
Notice that the operator< is now a const function.
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.
I am getting an error using std::find on the following structure ...
struct ComplianceOrderRecord {
explicit ComplianceOrderRecord(IOrder& order);
bool operator ==(const ComplianceOrderRecord& other) const;
double price;
};
inline bool ComplianceOrderRecord::operator ==(const ComplianceOrderRecord& other) const {
return price == other.price;
}
I use it as follows...
inline void Compliance::RemoveComplianceOrderRecord(const ComplianceOrderRecord& order) {
auto it = std::find(m_compliantOrderList.begin(),
m_compliantOrderList.end(), order);
if(it == m_compliantOrderList.end()) {
return;
}
m_compliantOrderList.erase(it);
}
The error is...
error C2679: binary '==' : no operator found which takes a right-hand operand of type 'const ComplianceOrderRecord' (or there is no acceptable conversion)
Any help in understanding this error would be very appreciated.
Your operator== should be a const member, or even better, a freestanding function.
This error can be reproduced if m_compliantOrderList is not a container<ComplianceOrderRecord >. (Perhaps it is a container of pointers, or some other completely unrelated class.
Edit:
Your equality operator can compare two instances of ComplianceOrderRecord, but find needs to compare a pointer against an object. Overloading an operator to perform this kind of comparison would be bizarre, so you could use find_if with a custom predicate, such as:
struct RecordIsEqualTo
{
const ComplianceOrderRecord* record;
RecordIsEqualTo(const ComplianceOrderRecord& r): record(&r) {}
bool operator() (const ComplianceOrderRecord* r) const { return *record == *r; }
};
std::find_if(m_compliantOrderList.begin(), m_compliantOrderList.end(),
RecordIsEqualTo(order) );
or a lambda version thereof.
Your operator== function should be const. As it is, you can't call it on a const object (or a reference to const.
Try a const method:
inline bool ComplianceOrderRecord::operator ==(const ComplianceOrderRecord& other) const {
return price == other.price;
}