operator[] ? lvalues!?

Programming, for all ages and all languages.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

operator[] ? lvalues!?

Post by earlz »

How can I make an object so that I can go MyObject[5]=93;

it says that operator[] takes exactly 1 argument, so how the crap is it possible?
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re: operator[] ? lvalues!?

Post by Colonel Kernel »

hckr83 wrote:How can I make an object so that I can go MyObject[5]=93;

it says that operator[] takes exactly 1 argument, so how the crap is it possible?
Return a non-const reference to the item that you want to receive the value 93. The 1 argument is the index -- 5 in your example. The assignment happens after operator[] returns.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: operator[] ? lvalues!?

Post by Candy »

hckr83 wrote:How can I make an object so that I can go MyObject[5]=93;

it says that operator[] takes exactly 1 argument, so how the crap is it possible?
int &operator[](int index);
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

It doesn't really make sense to me, but it works...so...
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Re: operator[] ? lvalues!?

Post by os64dev »

Candy wrote:
hckr83 wrote:How can I make an object so that I can go MyObject[5]=93;

it says that operator[] takes exactly 1 argument, so how the crap is it possible?
int &operator[](int index);
ahum.. because none of the members change it should be:

Code: Select all

int &operator[](int index) const;
:wink:
Author of COBOS
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re: operator[] ? lvalues!?

Post by Colonel Kernel »

os64dev wrote:
Candy wrote:
hckr83 wrote:How can I make an object so that I can go MyObject[5]=93;

it says that operator[] takes exactly 1 argument, so how the crap is it possible?
int &operator[](int index);
ahum.. because none of the members change it should be:

Code: Select all

int &operator[](int index) const;
:wink:
If you take "const" literally, yes, but it is not always a good idea to do so. Think about the bigger picture. Do you really want to allow code like this?

Code: Select all

const MyClass MyObject; // Should NEVER change!
MyObject[5] = 93; // Whoops, we made operator[] const and let something change...
Last edited by Colonel Kernel on Wed Oct 17, 2007 11:35 am, edited 1 time in total.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

ok but f you take "const" literally, yes, but it is not always a good idea to do so. Think about the bigger picture. Do you really want to allow code like this?

Code: Select all

const MyClass MyObject; // Should NEVER change!
MyObject[5] = 93; // Whoops, we made operator[] and let something change...
maybe i misunderstood but:

Code: Select all

int &operator[](int index) const;
just tells the compiler that this member function does not change the content of the current object and can generate more efficient code. The const here does not specifie a constant return value or a constant object. The code example you gave will not compile.
Author of COBOS
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

os64dev wrote:maybe i misunderstood but:

Code: Select all

int &operator[](int index) const;
just tells the compiler that this member function does not change the content of the current object and can generate more efficient code.
Actually it tells the compiler that this function is valid for const objects. Without the trailing const in the function declaration, a function can only be called for non-const objects.
Colonel Kernel wrote:Do you really want to allow code like this?
Do you really want to disallow code like this (which you would if you did not declare the operator const)?

Code: Select all

const MyClass myObject( ... );
cout << myObject[5];
Depending on the actual semantics of MyClass, you could write something like this to disallow the code you objected to:

Code: Select all

class MyClass {
    public:
        MyClass const & operator[]( int index ) const;
        MyClass & operator[]( int index );
};
That way, the reference returned by operator[]() is const if the MyClass object is const, and non-const otherwise.
Every good solution is obvious once you've found it.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

hmm, it seems i have to re-read the c++ book again.

EDIT: me confused.

constant member function
Author of COBOS
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

Solar wrote:Do you really want to disallow code like this (which you would if you did not declare the operator const)?

Code: Select all

const MyClass myObject( ... );
cout << myObject[5];
Of course not.
Depending on the actual semantics of MyClass, you could write something like this to disallow the code you objected to:

Code: Select all

class MyClass {
    public:
        MyClass const & operator[]( int index ) const;
        MyClass & operator[]( int index );
};
That way, the reference returned by operator[]() is const if the MyClass object is const, and non-const otherwise.
Exactly.

Next time I will endeavour to tell more than just half the story. :P
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: operator[] ? lvalues!?

Post by Candy »

os64dev wrote:ahum.. because none of the members change it should be:

Code: Select all

int &operator[](int index) const;
:wink:
Actually, if you return a reference to a pointer-contained object in this object, this would compile for const objects and be wrong - since you do change the state (or by const-capable actions you perform allow const object visible behaviour to change). Use the method Solar suggested - make two, one for const and one for non-const. Oh, and if you still use MSVC, kick it. VS2005 can't distinguish between const and non-const in at least the copy constructor, so I'm somewhat doubting it can do the other cases.
I refute your attempt to pass MSDN as C++ documentation. Not to mention the non-HTML compatible link.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Oh, and if you still use MSVC, kick it. VS2005 can't distinguish between const and non-const in at least the copy constructor, so I'm somewhat doubting it can do the other cases.
i use a gcc/g++ cross compiler so no issues here
I refute your attempt to pass MSDN as C++ documentation. Not to mention the non-HTML compatible link.
lol
Author of COBOS
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

You "could" do it the manual way.

Code: Select all

myObject *myArray;

int NumberOfItems = 5;

myArray[] = new char[NumberOfItems * sizeof(myObject)];
for(int i = 0; i < NumberOfItems; i++)
    myArray[i].myArray(); // call the constructor
then to clean up:

Code: Select all

for(int i = 0; i < NumberOfItems; i++)
    myArray[i].~myArray(); // call the deconstructor
delete myArray;
My OS is Perception.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

MessiahAndrw wrote:You "could" do it the manual way.

Code: Select all

myObject *myArray;

int NumberOfItems = 5;

myArray[] = new char[NumberOfItems * sizeof(myObject)];
for(int i = 0; i < NumberOfItems; i++)
    myArray[i].myArray(); // call the constructor
then to clean up:

Code: Select all

for(int i = 0; i < NumberOfItems; i++)
    myArray[i].~myArray(); // call the deconstructor
delete myArray;
And what exactly, aside from a load of code and a high complexity, does this add over

Code: Select all

myObject myArray[5];
?
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

In my way you could unwrap the loop that calls the constructors so that each array element can be passed individual constructor parameters.
My OS is Perception.
Post Reply