Reputation: 7121
I am trying to define some operators.
I do it according to this documentation:
http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html
Is there an operator that should be defined twice?
I think that it's the index operator. am I right? I defined it such as:
int operator [] (const int power) const{
// here there is some code
}
Assuming I implement it correctly, what's about the operator that should have be defined twice?
Does it support the next things?
a[1] = 3;
cout << a[1]; // I defined the << operator
any help appreciated!
Upvotes: 1
Views: 102
Reputation: 114461
To support assignment there are two options
[]
returns a reference[]
returns a proxy object that implements assignmentThe first case is the simplest, but doesn't allow you to distinguish between read and write operations. The second method is a bit more complex but allows more control:
An example of approach (2) is the following
struct MyArray {
std::vector<int> v;
MyArray(int n) : v(n) {}
struct ItemRef {
MyArray& a;
int index;
ItemRef(MyArray& a, int index)
: a(a), index(index)
{}
int operator=(int x) {
printf("Writing to element %i\n", index);
a.v[index] = x;
return x;
}
operator int() {
printf("Reading element %i\n", index);
return a.v[index];
}
};
ItemRef operator[](int index) {
if (index < 0 || index >= int(v.size()))
throw std::runtime_error("Invalid index");
return ItemRef(*this, index);
};
};
Upvotes: 1
Reputation: 126412
I think that it's the index operator. am I right?
Almost. It is called the subscript operator, and it must accept one single argument. Your operator accepts two, and that makes your code illegal.
Does it support the next things?
Supposing you have a properly written operator []
(without knowing some context from the logic of your application I cannot tell how to write one), then both the instructions you mention should be supported.
However, in order for this:
a[1] = 3;
To be legal (if a fundamental type is returned), operator []
should return an lvalue reference - therefore, int&
and not int
. Of course, this means the object to which the lvalue reference is bound cannot be a local object or a temporary, because that would mean returning a dangling reference.
int& operator [] (const int power) { // <== The function cannot be "const" if you
// ^ // are returning a non-const lvalue ref
// to a data member or element of a data
// member array
// here there is some code
}
You may also want a const
version of the subscript operator:
int operator [] (const int power) const {
// No need to use a int const& ^^^^^
// here, that is basically the This member function can be const, since it is
// same as returning an int by neither modifying the object on which it is
// value invoked, nor returns any non-const lvalue ref
to a data member or an element of data member
// here there is some code
}
Upvotes: 2
Reputation: 500167
You may want to have both a const
and a non-const
versions of the operator:
int operator[](int index) const { ... }
int& operator[](int index) { ... }
This will permit both usages given in your example. It will also permit the second usage even if a
is const
.
Upvotes: 2