468,765 Members | 1,598 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,765 developers. It's quick & easy.

Operator () overloading, wrong overload gets called

Hi all,

Im having a problem with my code. Im programming a vector class,
and am trying to overload the () operator in 2 different situations.
The first situation is to assign values, e.g. Y = X(1,2), the elements
1 and 2 of X gets assigned to Y. In this case, the operator ()
overload should create a copy that is unmodifiable. In the 2nd case, I
want do assign values to elements 1 and 2, e.g. X(1,2) = Y. Then in
this case, the values must be updated. I update by instantiating a
custom iterator class which has an overloaded = operator. Below is my
code. Sorry its a little long.

The issue now is that when I do Y = X(1,2), I always end up calling
the overload that is meant for the 2nd situation, rather than the
first. I hope I can get some advice.

Thanks in advance.

//************************************************** ******
// Main Vector Class
template <typename TYPE>
class Vector {
vector<TYPEv;
public:
//************************************************** ******
// Selectors
const TYPE& operator[](const int& k) const { return v[k]; } //default
[] indexing
const TYPE& operator()(const int& k) const {return v[k];}
int size() const {return v.size();} //returns the size

//************************************************** ******
// VectorItr Class
// this is a custom iterator class for Vector
// it wraps the standard vector iterator class
class VectorItr : public
std::iterator<std::random_access_iterator_tag, TYPE{
typename vector<TYPE>::iterator vitr;
int n; int *ptr;
public:

//assignments
VectorItr& operator= (const Vector<TYPE>& rhs) {
//using the iterator, populate the Vector<TYPE>
if (ptr == NULL) //for range
rhs.assign(vitr,n,rhs);
else {
for (int k=0; k<n; k++)
*(vitr+ptr[k]) = rhs[k];
}
return *this; //should i return this?
}

//************************************************** ******
// Constructors and Destructor
VectorItr() { };
~VectorItr(){ };

VectorItr( Vector<TYPE>& val, const int& i, const int& j) {
//this is used for range assignment
//this constructor is used to initialize the beginning of the
//iterator, and the number of elements that need to be assigned
vitr = val.begin()+i; n = j-i+1; ptr = NULL;
}

VectorItr( Vector<TYPE>& val, int ind[], const int n2) {
//this is used for index assignment
//this constructor is used to initialize the beginning of the
//iterator, and the number of elements that need to be assigned
vitr = val.begin(); n = n2; ptr = &ind[0];
}

};

const Vector<TYPEoperator()(const int& i, const int& j) const
{
return Vector<TYPE>(*this, i, j);
}

VectorItr operator()(const int& i, const int& j)
{
return VectorItr (*this, i, j);
}

//************************************************** ******
// Constructors and Destructor
Vector() { };
~Vector(){ };

//************************************************** ******
// Copiers
//copy constructors
Vector( const Vector<TYPE>& val) { //copy constructor for
intermediate results (like x + y)
for (int k = 0; k < val.size(); k++)
v.push_back(val[k]);
}
Vector( const Vector<TYPE>& val, const int& i, const int& j) {
//this constructor is used to create copy when indexing a range
for (int k = i; k <=j; k++){
if (k<val.size())
v.push_back(val[k]);
else v.push_back(0);
}
}
//can i make an initialization that does something like v = {1, 2 3};

//assignments
Vector<TYPE>& operator=(const Vector<TYPE>& rhs) {
v.clear();
for (int k = 0; k < rhs.size(); k++)
v.push_back(rhs[k]);
return *this;
}

//************************************************** ******
// vector container functions
void push_back(TYPE val) {v.push_back(val);}
typename vector<TYPE>::iterator begin() { return v.begin();}
typename vector<TYPE>::iterator end() { return v.end();}
void assign(typename vector<TYPE>::iterator itr, const int& n, const
Vector<TYPE>& val) const {
//Maybe I should group this under copiers
for (int k=0; k<n; k++){
*itr = val[k]; itr++;
}
//return *this; //should i return this?
}

template <size_t N//trick to get array size in automatically!
Vector<TYPE>& assign(int (&val)[N]) {
v.assign(val, val+N);
return *this;
}
};
Sep 10 '08 #1
1 1399
On Sep 10, 11:43 am, fabian....@gmail.com wrote:
I am doing the proxy thing, that is done by the VectorItr
Class.
Apparently not correctly.
Essentially my code works only in the following situation:

template <typename TYPE>
void ModifyValues(const Vector<TYPE>& x){
Vector<inty;
//put in some values into y.. lets say {3,4}
y = x(0,1);
}
int main (){
Vector<intx;
//put in some values into x.. lets say { 0, 1, 2}
//try to index 2 values of x and change y
return 0;
}
In this situation, Vector x is passed into the function
ModifyValues() as a const, thus the const overloaded ()
operator will kick in.
However, in the following situation, it will not work:
int main (){
Vector<intx,y;
//put in some values into x.. lets say { 0, 1, 2}
//put in some values into y.. lets say {3,4}
//try to index 2 values of x and change y
y = x(0,1); <---- doesnt work, will call the non-const version
of the operator() overload
Which is correct. Overload resolution is determined uniquely by
the types, and since the type of x is not const, you get the
non-const operator().

This is where the proxy kicks in. The non const version has
returned a proxy, not a Vector. Supposing that the assignment
operator of Vector requires a Vector, you need a conversion. So
you define a user defined conversion to Vector in the proxy
class, which returns whatever the const operator() would have
returned.
x(0,1) = y; <------ however this works.
return 0;
}
If I do not pass Vector x into a function, and specify it to
be const, the const overload never kicks in.
Which it shouldn't. It's up to you to make the proxy work
correctly in rvalue contexts. (Look at the example code I
posted. Or better yet, read up on proxies---if memory serves me
right, Scott Meyers discusses them in one of his books.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 10 '08 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

16 posts views Thread by Edward Diener | last post: by
2 posts views Thread by Kamran | last post: by
3 posts views Thread by y-man | last post: by
11 posts views Thread by jakester | last post: by
9 posts views Thread by sturlamolden | last post: by
14 posts views Thread by Jess | last post: by
8 posts views Thread by pauldepstein | last post: by
2 posts views Thread by rn5a | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.