473,320 Members | 2,104 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,320 software developers and data experts.

using array operators for lvalue and rvalue?

Does anyone have an example of how to create a class which describes
and array, such that I can use the subscript operator[] on both the
left and right side of an assignment statement? This is as close as I
can get, but I feel it's kludgey and slow...

#include <iostream.h>

template<class T>
class foo {
T *data;

public:
foo(int size) { data=new T[size]; }
~foo() { delete[] data; }

class helper {
T &item;
public:
helper(T &item_) : item(item_) {}
T &operator=(const T& other) {
cout <<"nonconst used as lvalue\n";
item=other;
return item;
}
operator const T&() const {
cout <<"nonconst used as rvalue\n";
return item;
}
};

helper operator[](int index) {
//don't know yet whether we are being used as l or r value
return helper(data[index]);
}
const T& operator[](int index) const {
cout <<"const used as rvalue\n";
return data[index];
}
};
int main()
{
foo<intx(10);
const foo<int&y=x;

cout <<"--- performing x[3]=10\n";
x[3]=10; //OK: nonconst used as lvalue

//cout <<"y[3]=11\n";
//y[3]=11; //BAD: const used as lvalue

cout <<"--- performing a=x[3]\n";
int a=x[3]; //OK: nonconst used as rvalue

cout <<"--- performing b=y[3]\n";
int b=y[3]; //OK: const used as rvalue

cout <<"--- performing x[3]=x[3]+5\n";
x[3]=x[3]+5; //OK: nonconst used as rvalue, then as lvalue

cout <<"result: x3 is " <<x[3] <<"\n";

return 0;
}
Jun 27 '08 #1
9 3311
On 2008-05-21 22:07, usao wrote:
Does anyone have an example of how to create a class which describes
and array, such that I can use the subscript operator[] on both the
left and right side of an assignment statement? This is as close as I
can get, but I feel it's kludgey and slow...
Perhaps I do not quite understand what you are asking for but something
like this should work:

class Foo
{
int i_;
public:
int& operator[](int i) { return 1; } // Replace 1 with a real element
};

int main()
{
Foo f;
f[1] = 1;
int i = f[1];
}

--
Erik Wikström
Jun 27 '08 #2
On May 21, 1:36*pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2008-05-21 22:07, usao wrote:
Does anyone have an example of how to create a class which describes
and array, such that I can use the subscript operator[] on both the
left and right side of an assignment statement? This is as close as I
can get, but I feel it's kludgey and slow...

Perhaps I do not quite understand what you are asking for but something
like this should work:

class Foo
{
* int i_;
public:
* int& operator[](int i) { return 1; } // Replace 1 with a real element

};

int main()
{
* Foo f;
* f[1] = 1;
* int i = f[1];

}

--
Erik Wikström
So, this can be done without the helper class?
Jun 27 '08 #3
usao wrote:
Does anyone have an example of how to create a class which describes
and array, such that I can use the subscript operator[] on both the
left and right side of an assignment statement? This is as close as I
can get, but I feel it's kludgey and slow...
"Slow"? Did you measure it? How slow is it? And compared to what?
#include <iostream.h>
There is no such header.
[.. idiomatic implementation of a proxy object returned by op[] ..]
That's not the only way to do it, but pretty much the "standard" approach.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #4
It compiles and runs fine on my Solaris host, but as for speed, I have
another really kludgey and unreadable C program which does basically
the same thing using function calls rather than array subscripting.
The C program (compiled with gcc) runs approx 200 times faster than
the C++ program (compiled with g++). I think the issue is around the
test for the const values which I have in the helper class. That seems
to add an extra layer of complexity which I don't worry about in the C
code.
But, hey, i fully admit that I dont know everything, and if there is a
better way to do this, that's what im looking for, so I can learn
somthing...

"Slow"? *Did you measure it? *How slow is it? *And compared to what?
#include <iostream.h>

There is no such header.
[.. idiomatic implementation of a proxy object returned by op[] ..]

That's not the only way to do it, but pretty much the "standard" approach.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #5
On May 21, 4:44 pm, usao <rwa...@gmail.comwrote:
So, this can be done without the helper class?
Yes. Do what Erik says. The [] operator returns a reference to an
element in the array; and so modifying values through that reference
directly modifies the data in the array.

You would probably want to do this as well, though:

template <class Tclass foo {
public:
T& operator [] (int index) { return data_[index]; }
const T& operator [] (int index) const { return data_[index]; }
private:
T *data_; // <-- allocated by something
};

void f () {
foo<std::stringx;
x[4] = x[0];
x[7] = "string";
std::string::const_iterator = x[8].begin();
}

Provide both a const and non-const version of the [] operator and the
compiler will use the appropriate one when necessary, you do not need
to think about it.

Also note that std::vector<exists and wraps an array. Depending on
your situation and requirements you may be able to save yourself some
future troubles by using the std implementation instead.

Jason
Jun 27 '08 #6
On May 21, 4:57 pm, usao <rwa...@gmail.comwrote:
It compiles and runs fine on my Solaris host,
It *happens* to compile find. And if the only machines you are
compiling it on have that header then, well, it does get the job done.

However, of course, sticking to the standards will increase
portability, which decreases kludginess and decreases future problems.
Modern C++ defines the correct header to be <iostream>. Using the
standard headers gives you future benefit with zero cost (find-replace
will be your friend if you change this in a large existing project).
The C program (compiled with gcc) runs approx 200 times faster than
the C++ program (compiled with g++). I think the issue is around the
test for the const values which I have in the helper class. That seems
to add an extra layer of complexity which I don't worry about in the C
code.
I can't speak for the speed. If you could provide full source and
compiler command lines for simple C and C++ code to use as a bench
mark, you might get some good insights here. However, the extra layer
of complexity is not actually necessary (see other reply). Returning
references to objects in the array from your [] operator provides
direct access to the data in the array. Providing both a const and non-
const implementation (as in other reply) gives you the flexibility you
want.
Jason
Jun 27 '08 #7
On May 21, 5:08 pm, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.comwrote:
Also note that std::vector<exists and wraps an array.
Documentation, FYI:
http://www.sgi.com/tech/stl/Vector.html

Jason
Jun 27 '08 #8
usao wrote:
On May 21, 1:36 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2008-05-21 22:07, usao wrote:
>>Does anyone have an example of how to create a class which describes
and array, such that I can use the subscript operator[] on both the
left and right side of an assignment statement? This is as close as I
can get, but I feel it's kludgey and slow...
Perhaps I do not quite understand what you are asking for but something
like this should work:

class Foo
{
int i_;
public:
int& operator[](int i) { return 1; } // Replace 1 with a real element

};

int main()
{
Foo f;
f[1] = 1;
int i = f[1];

}

--
Erik Wikström

So, this can be done without the helper class?
It can if you *don't care* to distinguish between the placement of the
indexing expression on the left of '=' from the right. Of course, since
the operator[] is defined here as non-const, you cannot use it on an
object that is const. Often two operator[] functions are defined, one
const and the other non-const, but used with a non-const object, the
indexing expression will call the non-const version (like in Erik's
program) and not the const version (as some expect).

If you need to distinguish (and call different operator[] functions)
between the use as lvalue and as rvalue:

f[1] = 1;
i = f[1];

then your original solution is essentially the answer. You can make it
a bit more straightforward if you return a proxy in both cases and make
the actual distinction (lvalue vs rvalue) in the assignment operator or
the conversion operator of the proxy, but it's essentially the same.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #9
usao wrote:
On May 21, 1:36*pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2008-05-21 22:07, usao wrote:
Does anyone have an example of how to create a class which describes
and array, such that I can use the subscript operator[] on both the
left and right side of an assignment statement? This is as close as I
can get, but I feel it's kludgey and slow...

Perhaps I do not quite understand what you are asking for but something
like this should work:

class Foo
{
int i_;
public:
int& operator[](int i) { return 1; } // Replace 1 with a real element

};

int main()
{
Foo f;
f[1] = 1;
int i = f[1];

}

--
Erik Wikström

So, this can be done without the helper class?
Yes. However, _sometimes_ proxy object offer additional benefits. E.g., if
you want to implement copy-on-write semantics, an exposed non-const
reference can be cumbersome. In that case, a proxy object would be the way
to go. Otherwise, it will just add unnecessary complexity.
Best

Kai-Uwe Bux
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Steven T. Hatton | last post by:
This is from the draft of the previous version of the Standard: http://www.kuzbass.ru:8086/docs/isocpp/expr.html 2- A literal is a primary expression. Its type depends on its form...
138
by: ambika | last post by:
Hello, Am not very good with pointers in C,but I have a small doubt about the way these pointers work.. We all know that in an array say x,x is gonna point to the first element in that...
24
by: Romeo Colacitti | last post by:
Hi, Does anyone here have a strong understanding for the meanings of the terms "lvalue" and "rvalue" as it pertains to C, objects, and different contexts? If so please share. I've been...
18
by: junky_fellow | last post by:
Consider an array. char arr; When we find sizeof(arr) ---> Output is 10, arr is treated as an object of 10 chars. When we say arr+1, ---> arr is treated as a pointer to char. Why is...
6
by: junky_fellow | last post by:
Hi all, Consider a piece of code: char arr; char *ptr; arr = ptr; <----- On compilation, I get an error for this line.
9
by: Kavya | last post by:
These were the questions asked to me by my friend 1. Operator which may require an lvalue operand, yet yield an rvalue. 2. Operator which may require an rvalue operand, yet yield an lvalue. ...
14
by: nobrow | last post by:
Yes I know what lvalue means, but what I want to ask you guys about is what are all valid lvalues ... a *a a *(a + 1) .... What else?
6
by: Lighter | last post by:
How to read "The lvalue-to-rvalue, array-to-pointer, and function-to- pointer standard conversionsare not applied to the left expressions"? In 5.18 Comma operator of the C++ standard, there is a...
6
by: Yarco | last post by:
I've alway thought lvalue means Left Value and rvalue means Right Value before i've read someone's article. It is said "lvalue = location value" and "rvalue = read value". Which one is right, then?
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.