More problems with subscript operator

S

Steve

Hi, I have a class called cList as so:

template<class T> class cList { // base class for Lists
private:
protected:
vector<T> tListOf; // field list container
public:
void Add(const T& t) {tListOf.push_back(t);} // add new object to list
unsigned int Count() { return tListOf.size(); } // number of list items

cList(); // default constructor
cList(const cList&); // copy constructor
cList& operator=(const cList&); // assignment constructor
virtual ~cList(); // destructor

T& operator[](int& pos) {return tListOf[pos];} // subscript operator
const T& operator[](const int& pos) {return tListOf[pos];} // subscript
operator
};


This is inherited by another class, cDataList, and another, cResultList. The
data list object is a list of cData objects, and the result list is a list
of cResult objects.

class cResultList : public cList<cResult> {
private:
// some stuff
public:
// c'tors etc
};

class cDataList : public cList<cData> {
private:
// some stuff
public:
// c'tors etc

cResultList Results;
};


The cDataList object contains a cResultList object called Results.

I then have a class called cDCF like so:

class cDCF {
private:
// some stuff
public:
// c'tors etc
cDataList Data;
};

My problem is, I'm struggling to access the elements of Results (the cResult
class has a 'value' member):

cDCF *dcf = new cDCF(myfilename);

float f = dcf->Data[1].Results[1].value;

This gives a compiler error saying:
operator+ not implemented in type cResultList for arguements of type 'int'

however, if I use this:

cDCF *dcf = new cDCF(myfilename);
cData d = dcf->Data[1];
float f = d.Results[1].value;

this works. Now I know it's something to do with how I'm using the subscript
operator, but I'm not sure what. Can anybody see what I'm doing wrong
please?

Thanks for your time,
Steve
 
G

Gianni Mariani

Steve said:
Hi, I have a class called cList as so:

It would really help if you posted a complete compilable example that
demonstrated your issue.
template<class T> class cList { // base class for Lists
private:
protected:
vector<T> tListOf; // field list container
public:
void Add(const T& t) {tListOf.push_back(t);} // add new object to list
unsigned int Count() { return tListOf.size(); } // number of list items

cList(); // default constructor
cList(const cList&); // copy constructor
cList& operator=(const cList&); // assignment constructor
virtual ~cList(); // destructor

T& operator[](int& pos) {return tListOf[pos];} // subscript operator
const T& operator[](const int& pos) {return tListOf[pos];} // subscript
operator

I suspect the operator above is probably not what you want.

T& operator[](int pos) {return tListOf[pos];}
const T& operator[](int pos) const {return tListOf[pos];}

I think passing an (int) or a (const int &) is really not going to be an
issue but I think you never want to oass an (int &) becuase that limits
what can be passed in as a subscript parameter.

The const [] operator need to be a const function.

This *might* be the issue you have, I don't know.
};


This is inherited by another class, cDataList, and another, cResultList. The
data list object is a list of cData objects, and the result list is a list
of cResult objects.

class cResultList : public cList<cResult> {
private:
// some stuff
public:
// c'tors etc
};

class cDataList : public cList<cData> {
private:
// some stuff
public:
// c'tors etc

cResultList Results;
};


The cDataList object contains a cResultList object called Results.

I then have a class called cDCF like so:

class cDCF {
private:
// some stuff
public:
// c'tors etc
cDataList Data;
};

My problem is, I'm struggling to access the elements of Results (the cResult
class has a 'value' member):

cDCF *dcf = new cDCF(myfilename);

float f = dcf->Data[1].Results[1].value;

This gives a compiler error saying:
operator+ not implemented in type cResultList for arguements of type 'int'

however, if I use this:

cDCF *dcf = new cDCF(myfilename);
cData d = dcf->Data[1];
float f = d.Results[1].value;

this works. Now I know it's something to do with how I'm using the subscript
operator, but I'm not sure what. Can anybody see what I'm doing wrong
please?

Thanks for your time,
Steve
 
S

Steve

Hi Gianni

T& operator[](int pos) {return tListOf[pos];}
const T& operator[](int pos) const {return tListOf[pos];}


This fixed the problem, many thanks.

I think passing an (int) or a (const int &) is really not going to be an
issue but I think you never want to oass an (int &) becuase that limits
what can be passed in as a subscript parameter.

The const [] operator need to be a const function.

I'm still trying to get to grips with when to pass by reference and when not
to.

Thanks again,
Steve
 
G

Gianni Mariani

Steve said:
Hi Gianni


T& operator[](int pos) {return tListOf[pos];}
const T& operator[](int pos) const {return tListOf[pos];}



This fixed the problem, many thanks.


I think passing an (int) or a (const int &) is really not going to be an
issue but I think you never want to oass an (int &) becuase that limits
what can be passed in as a subscript parameter.

The const [] operator need to be a const function.


I'm still trying to get to grips with when to pass by reference and when not
to.

The only time you want to pass by (non const) reference is when you want
the function being called to modify the caller's parameter.

Passing by value or by const & depends on what you're doing. For
example, passing a large struct by value may be unwise because the
construction and destruction are expensive in resources, passing an int
by value is probably less expensive resource wise than passing by
reference. However, there is one other issue, passing a by const &
means that you are required not to modify the parameter while in the
function being called otherwise you will get unpredictable behaviour.

See this:

int x = 2;

int func( const int & z )
{
x = z + 1;
return z * x;
}

int main()
{
return func( x );
}

The return value from main is undefined. This is because func()
modifies it's own const parameter meaning that it's not really const
after all. The compiler may make the optimization of reading the value
of z only once and use it in both expressions (note that the compiler is
free to not make the optimization according to the standard).

If we declare func() as "int func( int z )" then there is a copy of the
value x passed into the function.

However, this is rarely an issue and the cost of making a copy is
usually far greater than passing a reference.
 
W

Woebegone

Hi Steve,
The only time you want to pass by (non const) reference is when you want
the function being called to modify the caller's parameter.

Passing by value or by const & depends on what you're doing.

Another consideration is whether you want polymorphic behaviour within your
function. A value parameter will always be read according to it's static
type, while a reference or pointer parameter behaves according to it's
dynamic type. Here's an example:

#include <string>
#include <iostream>

class C {
public:
virtual const std::string name() const{
return "class C";
}
};

class D : public C {
public:
const std::string name() const {
return "class D";
}
};

void f_ref(const C& c) {
std::cout << "f_ref sees: " << c.name() << "\n";
}

void f_ptr(const C* c) {
std::cout << "f_ptr sees: " << c->name() << "\n";
}

void f_val(const C c) {
std::cout << "f_val sees: " << c.name() << "\n";
}

int main() {
D d;
f_ref(d);
f_ptr(&d);
f_val(d);
return 0;
}

Output:
f_ref sees: class D
f_ptr sees: class D
f_val sees: class C
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top