0

I have a class Foo that encapsulates access to a vector and provides access to it via the subscript operator:

typedef int* IntPtr; 

class Foo {
   std::vector<IntPtr> bars;
   IntPtr& operator[](size_t idx) {
      return bars[idx];
   }
};

In class Bar i want to use Foo. While solution 1 works, it is rather inconvenient. I would prefer something like solution 2. Obviously, a method call (even if it returns an lvalue) can't be assigned something, albeit the method call doesn't do anything else than solution 1.

class Bar {
   Foo *foo; //some initialization

   IntPtr helper(size_t idx) {
      return (*foo)[idx];
   }

   void barfoo() {
      size_t baz = 1;
      IntPtr qux;

      //solution 1
      qux = (*foo)[baz];  //works
      (*foo)[baz] = &1;    //works

      //solution 2
      qux = helper(baz);  //works
      helper(baz) = &1;    //does not work: "expression is not assignable"
   }     
};

Question: How can I simplify the usage of an overloaded subscript operator?

EDIT: Changed used type to from int to int*. Sorry, I screwed up when creating the example.

I guess the problem is because of the twisted int*&.

3
  • 1
    Works for me (once I fix the accessibility of Foo::operator[]). You certainly can assign to an lvalue reference returned by a function. Are you sure the error comes from that code? Commented Nov 27, 2013 at 16:32
  • if helper returns a reference your solution 2 works Commented Nov 27, 2013 at 16:33
  • What compiler are you using? Because that line should work... Commented Nov 27, 2013 at 16:37

2 Answers 2

1

The best way is to write a regular method, e.g Foo::at(size_t idx), providing the same functionality as your operator. Notice that the STL does the same (just take a look at std::vector). You can then simply call foo->at(baz);. To avoid rendundancy you could change the implementation of operator[]:

int& operator[](size_t idx) {
    return at(idx);
}

In your snippet, you cant assign a value to the return because you have forgotten to return a reference.

Not that nice but an alternative would be foo->operator[](baz); though I strongly discourage you to write such an ugly code.

Sign up to request clarification or add additional context in comments.

6 Comments

Even then foo->at(baz) = 1 would not be possible.
@mort Why not? It should be.
Eh? Why not? at is a regular method, you can call it just like every other method. You call a method from a pointer with the -> operator.
Well, the STL defines both operator[] and at() because they have entirely different semantics: at() does bounds checking, operator[] does not. If it were not for this semantic difference, having both functions would simply be code bloat, i. e. something that should not be done.
Found the mistake (see my answer). I upvoted your answer (it lead me the right way...) but don't want to accept it, as it is not actually the right one. If you edit it, I'll happily reward you by accepting it :)
|
0

Darn. I just forgot to let helper return the value via a reference:

IntPtr& helper(size_t idx) 

or

int*& helper(size_t idx)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.