Subscript operator overloading with vectors

O

olson_ord

Hi,

I am not exactly new to C++, but I have never done operator
overloading before.
I have some old code that tries to implement a Shift Register - but I
cannot seem to get it to work. Here's a simpler version of it.

-------------------- main.cpp---------------------------

# include <iostream>
# include <vector>
# include <cassert>

class ShiftRegister {
public:
ShiftRegister(unsigned size) : _reg(size) {

}

bool& operator[](unsigned ix) {

return _reg[ix];
}

const bool& operator[](unsigned ix) const {

return _reg[ix];
}

private:
std::vector<bool> _reg;
};


int main(int argc, char* argv[]) {

ShiftRegister sftreg(2);

}


------------------ end of main.cpp ----------------

The above contains two definitions of the subscript operator one
ordinary and one constant. Compiling this I get
1. For the ordinary or variable subscript operator
error: could not convert `std::vector<bool,
_Alloc>::eek:perator[](unsigned int) [with _Alloc =
std::allocator<bool>](ix)'
to `bool&'

2. For the constant subscript operator
warning: returning reference to temporary

I think I am missing something here, but looking in books or on the
internet does not make me understand what I am doing wrong i.e. they
seem to be doing the same thing (but with arrays or pointers - not with
vectors.)

I hope someone has some ideas on how to get this to work.
Thanks a lot.
O.O.
 
B

Ben Radford

Hi,

I am not exactly new to C++, but I have never done operator
overloading before.
I have some old code that tries to implement a Shift Register - but I
cannot seem to get it to work. Here's a simpler version of it.

-------------------- main.cpp---------------------------

# include <iostream>
# include <vector>
# include <cassert>

class ShiftRegister {
public:
ShiftRegister(unsigned size) : _reg(size) {

}

bool& operator[](unsigned ix) {

return _reg[ix];
}

const bool& operator[](unsigned ix) const {

return _reg[ix];
}

private:
std::vector<bool> _reg;
};


int main(int argc, char* argv[]) {

ShiftRegister sftreg(2);

}


------------------ end of main.cpp ----------------

The above contains two definitions of the subscript operator one
ordinary and one constant. Compiling this I get
1. For the ordinary or variable subscript operator
error: could not convert `std::vector<bool,
_Alloc>::eek:perator[](unsigned int) [with _Alloc =
std::allocator<bool>](ix)'
to `bool&'

2. For the constant subscript operator
warning: returning reference to temporary

I think I am missing something here, but looking in books or on the
internet does not make me understand what I am doing wrong i.e. they
seem to be doing the same thing (but with arrays or pointers - not with
vectors.)

I hope someone has some ideas on how to get this to work.
Thanks a lot.
O.O.

My first thoughts on this are that it's to do with the specialisation of
the std::vector template for bools (ie std::vector<bool> is a vector of
bits not bools which the standard says must be at least 1 byte). Does
the code work if you use another primitive type?
 
B

Ben Radford

Ben said:
Hi,

I am not exactly new to C++, but I have never done operator
overloading before.
I have some old code that tries to implement a Shift Register - but I
cannot seem to get it to work. Here's a simpler version of it.

-------------------- main.cpp---------------------------

# include <iostream>
# include <vector>
# include <cassert>

class ShiftRegister {
public:
ShiftRegister(unsigned size) : _reg(size) {

}

bool& operator[](unsigned ix) {

return _reg[ix];
}

const bool& operator[](unsigned ix) const {

return _reg[ix];
}

private:
std::vector<bool> _reg;
};


int main(int argc, char* argv[]) {

ShiftRegister sftreg(2);

}


------------------ end of main.cpp ----------------

The above contains two definitions of the subscript operator one
ordinary and one constant. Compiling this I get
1. For the ordinary or variable subscript operator
error: could not convert `std::vector<bool,
_Alloc>::eek:perator[](unsigned int) [with _Alloc =
std::allocator<bool>](ix)'
to `bool&'

2. For the constant subscript operator
warning: returning reference to temporary

I think I am missing something here, but looking in books or on the
internet does not make me understand what I am doing wrong i.e. they
seem to be doing the same thing (but with arrays or pointers - not with
vectors.)

I hope someone has some ideas on how to get this to work.
Thanks a lot.
O.O.

My first thoughts on this are that it's to do with the specialisation of
the std::vector template for bools (ie std::vector<bool> is a vector of
bits not bools which the standard says must be at least 1 byte). Does
the code work if you use another primitive type?

To elaborate, the bools in std::vector<bool> don't exist as bools. When
you access the vector you get given a temporary bool created by
examining whether the relative bit is on or off. Since it is only
temporary you can't return a reference to it. I hope that's a bit
clearer than my initial reply =)
 
O

olson_ord

Very, very good guess Ben. I never realised or even thought about it.
Yes I tried to compile my program with this bool replaced by int - and
it works.
However I actually need bool 's. (If you have any idea about what a
Shift Register is - you would know why I don't really require
integers.) I also wanted to optimize this for speed. I would think
about this problem and see what can be done - now that I at least know
what the problem is.
Thanks once again.
O.O.
 
B

Ben Pope

Hi,

I am not exactly new to C++, but I have never done operator
overloading before.
I have some old code that tries to implement a Shift Register - but I
cannot seem to get it to work. Here's a simpler version of it.

I hope someone has some ideas on how to get this to work.
Thanks a lot.

Are you aware of std::bitset?

Ben Pope
 
R

roberts.noah

Very, very good guess Ben. I never realised or even thought about it.
Yes I tried to compile my program with this bool replaced by int - and
it works.
However I actually need bool 's. (If you have any idea about what a
Shift Register is - you would know why I don't really require
integers.)

Use chars...there really isn't a diff anyway.
 
M

Marcus Kwok

Ben Radford said:
To elaborate, the bools in std::vector<bool> don't exist as bools. When
you access the vector you get given a temporary bool created by
examining whether the relative bit is on or off. Since it is only
temporary you can't return a reference to it. I hope that's a bit
clearer than my initial reply =)

Yes, for more information:

When Is a Container Not a Container?
http://www.gotw.ca/publications/mill09.htm

vector<bool> Is Nonconforming, and Forces Optimization Choice
http://www.gotw.ca/publications/N1185.pdf

vector<bool>: More Problems, Better Solutions
http://www.gotw.ca/publications/N1211.pdf
 
J

Jim Langston

You got your answers in other posts. Just a comment on your code

Hi,

I am not exactly new to C++, but I have never done operator
overloading before.
I have some old code that tries to implement a Shift Register - but I
cannot seem to get it to work. Here's a simpler version of it.

-------------------- main.cpp---------------------------

# include <iostream>
# include <vector>
# include <cassert>

class ShiftRegister {
public:
ShiftRegister(unsigned size) : _reg(size) {

}

_reg is a no no. You shouldn't use an underscore as the first char of a
variable/function/whatever.
 
D

Daniel T.

"Jim Langston said:
You got your answers in other posts. Just a comment on your code



_reg is a no no. You shouldn't use an underscore as the first char of a
variable/function/whatever.

There is absolutely no problem with a member-variable having a
underscore as its first character as long as the next character is not
an upper-case letter.

The restrictions are as follows:

any global-scope name beginning with _.
any name beginning with _ followed by an upper-case letter.
any name containing __.
 
O

olson_ord

Thanks a lot guys for your posts and your comments.
Regarding Ben's (Ben Pope - because there are two Bens here)
suggestion of std::bitset - I cannot use it, because of the same
problem of providing a reference i.e. a pointer.

I finally got this working by declaring my own class - that had a
bool as its private member.
Thanks to all.
O.O.
 
B

Ben Pope

Thanks a lot guys for your posts and your comments.
Regarding Ben's (Ben Pope - because there are two Bens here)
suggestion of std::bitset - I cannot use it, because of the same
problem of providing a reference i.e. a pointer.

I was assuming you could just use the std::bitset as your register:

typedef std::bitset<16> my16bitShiftRegister;

my16bitShiftRegister reg = 0x1234;
reg <<= 4; // reg contains 0x2340 (I think :)

I didn't know what other functionality you required.
I finally got this working by declaring my own class - that had a
bool as its private member.
Thanks to all.
O.O.

Job done then!

Ben Pope
 

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

Similar Threads

operator overloading 9
transform, boost::lambda and subscript 1
overloading operator-> 0
subscript overloading 6
Operator Overloading 1
Overloading Subscript operator 5
playing with vectors 5
printing vectors 4

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top