Fighting with overloading the [] operator in C++

Started by
19 comments, last by Xai 17 years ago
I've been writing a small wrapper class that uses the stl vector inside of it. I'm working on overloading the [] operator. I was under the impression that there were 2 different versions of it that I should implement. One for reads and one for writes. I'm at work, so I don't have access to my C++ reference books at home, but I thought the fuctions were some where along the lines of type operator [] (const int i) const; // Read type& operator [] (const int i); // Write THe wrapper class I'm writing has a read only property to it, and I want to restrict changing a value if the flag is set. The problem I get is both member functions compile fine in MSVC 2005. But at runtime, on both read and write operations the "type& operator [] (const int i)" version is called. There really isn't a good way I can think of to implement the write protection in a single function, since it has to pass by reference and doesn't really have any control over what is happening to the variable at that point. Am I just misunderstanding the concept or just getting some bit of syntax wrong

//  Very simple example
class List
{
public:
     List() : m_bReadOnly(true)
     {
     }

int operator [] (const int i) const  // Read
{
     return m_List;
}
int& operator [] (const int i);  // Write
{
     if(m_bReadOnly)
     {
          throw 1;
     }

     return m_List;
}

private:
std::vector<int> m_List;
bool m_bReadOnly;
};

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Advertisement
The const version is only ever called when invoked from a const function or a const instance or reference to your class. All other invocations will use the non-const version.
And it doesn't look like that. Both return references, and neither take const ints (there is no reason for function arguments to be const types, ever). The prototypes are as follows:

type const& operator [] (size_t i) const; // Read-only
type & operator [] (size_t i); // Read-write
That makes sense. Thank you for the fast replies.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Quote:Original post by Sneftel
And it doesn't look like that. Both return references, and neither take const ints (there is no reason for function arguments to be const types, ever). The prototypes are as follows:

type const& operator [] (size_t i) const; // Read-only
type & operator [] (size_t i); // Read-write


editing your statement:

there is no reason for non-reference function arguments to be const types
Also, if you need to provide run-time write protection to a value you cannot use these functions, because there is no way to hook into a write into the int& you return to block it.

You will have to go to some form of setter function.
Quote:Original post by Xai
Quote:Original post by Sneftel
And it doesn't look like that. Both return references, and neither take const ints (there is no reason for function arguments to be const types, ever). The prototypes are as follows:

type const& operator [] (size_t i) const; // Read-only
type & operator [] (size_t i); // Read-write


editing your statement:

there is no reason for non-reference function arguments to be const types


Actually references are const by nature.. You meant that there are reasons for references to be referencing const data.
You probably already know that, but someone else reading the post might get confused.
[ my blog ]
Quote:Original post by arithma
Quote:Original post by Xai
Quote:Original post by Sneftel
And it doesn't look like that. Both return references, and neither take const ints (there is no reason for function arguments to be const types, ever). The prototypes are as follows:

type const& operator [] (size_t i) const; // Read-only
type & operator [] (size_t i); // Read-write


editing your statement:

there is no reason for non-reference function arguments to be const types


Actually references are const by nature.. You meant that there are reasons for references to be referencing const data.
You probably already know that, but someone else reading the post might get confused.


And now I see that you weren't talking about references themselves.
[ my blog ]
Quote:Original post by Xai
there is no reason for non-reference function arguments to be const types

There is ESPECIALLY no reason for reference function arguments to have const type, since there is no reason for references themselves to be const (see here). It is often useful, however, for references to be references to const types.
Quote:Original post by Rattrap
The wrapper class I'm writing has a read only property to it, and I want to restrict changing a value if the flag is set. The problem I get is both member functions compile fine in MSVC 2005. But at runtime, on both read and write operations the "type& operator [] (const int i)" version is called. There really isn't a good way I can think of to implement the write protection in a single function, since it has to pass by reference and doesn't really have any control over what is happening to the variable at that point. Am I just misunderstanding the concept or just getting some bit of syntax wrong

That sounds very much like the .NET collections, and the way they do what they do is through runtime polymorphism. You'd have to have virtual setters of some form.

I personally detest .NET's collection types. To make a read only version of a custom collection, you have to write a new class that wraps the read/write version, or build in checks into your original class all over the place. Additionally, you have to use the polymorphic behavior, which while not horrible, would be nice to avoid when possible. Another problem is that all write attempts on read-only collections are only caught at run-time, never compile-time.

I find the const-correctness idea of C++ to be preferable. (And when you really do need runtime behavior, you can still program it it; it's just not available in the standard collections).
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

This topic is closed to new replies.

Advertisement