Jump to content
  • Advertisement
Sign in to follow this  
Rattrap

Fighting with overloading the [] operator in C++

This topic is 4110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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;
};

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!