How to detect read or write access to a user defined array?

J

jacob navia

Hi

Suppose that I want to create an array of read only items

I overload the [ ] operator. How can I detect if I am being called
within a read context
foo = Array[23];

or within a write context
Array[23] = foo;

As far as I remember, this is not possible in C++.

Thanks
 
J

jacob navia

Abdo said:
If you want a read-only array, then why don't you return a const reference?

Abdo Haji-Ali
Programmer
In|Framez

Obviously I need to initialize the array.
I want a read only array MOST of the time.

Context:

We had a discussion in comp.lang.c about this, and I just want to know
if it is possible in C++ to detect within the overloaded operator [ ]
if we are being called for a read or for a write.

Thanks
 
A

Abdo Haji-Ali

jacob navia said:
Hi

Suppose that I want to create an array of read only items
If you want a read-only array, then why don't you return a const reference?

Abdo Haji-Ali
Programmer
In|Framez
 
Z

z.cHris

if it is possible in C++ to detect within the overloaded operator [ ]
if we are being called for a read or for a write.

Well then, I don't think you can. Basically a "read" operation is not always
a read. Consider the following:
int& foo = Array[0]; // Assuming that Array is an integer array

In that case one can use 'foo' for "reading":
int iValue = foo;

Or for writing:
foo = iValue;

Without even refering to the original user array.

Abdo Haji-Ali,
Programmer
In|Framez

PS: I would make this indexer read only and provide other function for
"one-time" write.

And also I could use *(Array + index) = value, to change the array
whatever you do to [].
So, if you want to achieve your goal, just overload the [] operator is
not enough.
 
A

Abdo Haji-Ali

jacob navia said:
We had a discussion in comp.lang.c about this, and I just want to know
if it is possible in C++ to detect within the overloaded operator [ ]
if we are being called for a read or for a write.
Well then, I don't think you can. Basically a "read" operation is not always
a read. Consider the following:
int& foo = Array[0]; // Assuming that Array is an integer array

In that case one can use 'foo' for "reading":
int iValue = foo;

Or for writing:
foo = iValue;

Without even refering to the original user array.

Abdo Haji-Ali,
Programmer
In|Framez

PS: I would make this indexer read only and provide other function for
"one-time" write.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

if it is possible in C++ to detect within the overloaded operator [ ]
if we are being called for a read or for a write.

Well then, I don't think you can. Basically a "read" operation is not always
a read. Consider the following:
int& foo = Array[0]; // Assuming that Array is an integer array

In that case one can use 'foo' for "reading":
int iValue = foo;

Or for writing:
foo = iValue;

Without even refering to the original user array.

Abdo Haji-Ali,
Programmer
In|Framez

PS: I would make this indexer read only and provide other function for
"one-time" write.

And also I could use *(Array + index) = value, to change the array
whatever you do to [].
So, if you want to achieve your goal, just overload the [] operator is
not enough.

Assuming that the items are stored in an array, that is.
 
R

Rolf Magnus

jacob said:
Obviously I need to initialize the array.

Then use the object through a const reference after initializing.
I want a read only array MOST of the time.

Context:

We had a discussion in comp.lang.c about this, and I just want to know
if it is possible in C++ to detect within the overloaded operator [ ]
if we are being called for a read or for a write.

It is not called "for a read or for a write". MyObject just calls the
operator[] on MyObject. What you do to the object returned by that
operator is a whole different story. So the answer to your question would
be "no". However, you could let the operator create a proxy object that
forwards read and write operations, which might be sufficient, depending on
what you want.
 
T

terminator

Hi

Suppose that I want to create an array of read only items

I overload the [ ] operator. How can I detect if I am being called
within a read context
foo = Array[23];

or within a write context
Array[23] = foo;

As far as I remember, this is not possible in C++.

Thanks

something like this will do for lots of cases:

template <class T>
struct contianer{
T& operator[](unsigned);
const T& operator[](unsigned) const;
};

but if you need a class for which iteration for read and write need
different algorithms, you can easily define an indexer class:

template <class T>
struct contianer{
struct indexer{
explicit indexer(T*const,unsigned i):me(T),index(i){};
operator T&()const;//this is the read function
indexer& operator=(const T&)const{/*the 'write' stuff
here*/};
protected:
T* const me;
const unsigned index;
private:
indexer(const indexer&);
};
indexer operator[](unsigned i){return indexer(this,i);};
const T& operator[](unsigned) const{return indexer(this,i).
(operator T&)();};
...//class definition continues
};

regards,
FM.
 
J

Jerry Coffin

Hi

Suppose that I want to create an array of read only items

I overload the [ ] operator. How can I detect if I am being called
within a read context
foo = Array[23];

or within a write context
Array[23] = foo;

Make it const and have it return a reference to const. This prevents you
from writing to the data (at all) via the operator:

class bad_subscript {};

template <class T>
class const_array {
T *data_;
size_t size_;
public:
const_array(T *init, size_t size) :
size_(size), data_(new T[size])
{
std::copy(init, init+size, data_);
}

T const &operator[](size_t subscript) const {
if (subscript > size_)
throw bad_subscript();
return data_[subscript];
}

T *raw_data() { return data_; }
size_t size() { return size_; }
};

raw_data() is a quick hack to allow writing to the data -- you haven't
said when or how you want to allow writing to the data, so I've provided
one way to do it. If you _only_ want to allow the data to be
initialized, you can eliminate it (and probably add more ctors to allow
more than one form of intialization).
 
T

terminator

but if you need a class for which iteration for read and write need
different algorithms, you can easily define an indexer class:

template <class T>
struct contianer{
struct indexer{
explicit indexer(T*const,unsigned i):me(T),index(i){}; explicit keyword is extra
......
private:
indexer(const indexer&);

oops!! delete last two lines(they were error) regards,
FM.
 
T

terminator

Hi

Suppose that I want to create an array of read only items
I guess you program in C# .if you need an array of read onlies,you
can:

template<class T>
struct container{
T& operator[](unsigned);
const T& operator[](unsigned)const;
....//etc
};

class my_class;

container<const my_class> read_list;

my_int=read_list[my_index];//ok
read_list[my_index]=my_int;//error @ compile time

container<my_class> my_list;

const container<my_class> & my_const_list_ref=my_list;

my_list[my_index];//call T& operator[](unsigned);
my_const_list_ref[my_index];//call const T& operator[](unsigned)const;

regards,
FM.
 
I

Ian Collins

jacob said:
Hi

Suppose that I want to create an array of read only items

I overload the [ ] operator. How can I detect if I am being called
within a read context
foo = Array[23];

or within a write context
Array[23] = foo;
You have to use another level of indirection, something like this:

#include <iostream>

template <typename Taget, typename ArrayType>
class Proxy {
Taget& target;
unsigned index;

public:

Proxy( Taget& target, unsigned index )
: target(target), index(index) {}

Proxy& operator=( ArrayType t ) {
std::cout << "rhs " << index << std::endl;
return *this;
}

operator ArrayType() const {
std::cout << "lhs " << index << std::endl;
return 42;
}
};

struct Test {
typedef Proxy<Test, int> ProxyType;

const ProxyType operator[]( unsigned index ) const {
return ProxyType(const_cast<Test&>(*this), index );
}

ProxyType operator[]( unsigned index ) {
return ProxyType(*this, index );
}
};

int main() {
Test test;

int n = test[0];

test[3] = 42;
}
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top