473,396 Members | 2,129 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

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 1720
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: Edward Diener | last post by:
Is there a way to override the default processing of the assignment operator for one's own __value types ? I realize I can program my own Assign method, and provide that for end-users of my class,...
2
by: Kamran | last post by:
Hi I have very little experience of C++, nevertheless I have been asked to write a gui using QT/QWT. I know that I should direct the question to the relevant mailing list and I have done that but...
3
by: y-man | last post by:
Hi, I am trying to get an overloaded operator to work inside the class it works on. The situation is something like this: main.cc: #include "object.hh" #include "somefile.hh" object obj,...
11
by: jakester | last post by:
I am using Visual C++ 2007 to build the code below. I keep getting linkage error. Could someone please tell me what I am doing wrong? The code works until I start using namespace for my objects. ...
9
by: sturlamolden | last post by:
Python allows the binding behaviour to be defined for descriptors, using the __set__ and __get__ methods. I think it would be a major advantage if this could be generalized to any object, by...
14
by: Jess | last post by:
Hi, I read about operator overloading and have a question regarding "operator->()". If I have two classes like this: struct A{ void f(); }; struct B{
8
by: pauldepstein | last post by:
The following code was written by a colleague -- to preserve confidentiality, the name of the class is changed: HisClass operator+ (const HisClass & h1, const HisClass & h2) { // some code here}...
2
by: rn5a | last post by:
I use VB.NET to create ASP.NET apps. If I am not wrong, there is something called method overloading in VB.NET (like in C#) which is one of the features in OOP (polymorphism) but does VB.NET also...
8
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.