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*&.

mort
  • 12,988
  • 14
  • 52
  • 97

2 Answers2

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.

Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
  • Even then `foo->at(baz) = 1` would not be possible. – mort Nov 27 '13 at 16:31
  • @mort Why not? It should be. – BoBTFish Nov 27 '13 at 16:33
  • 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. – Sebastian Hoffmann Nov 27 '13 at 16:34
  • 3
    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. – cmaster - reinstate monica Nov 27 '13 at 16:35
  • 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 :) – mort Nov 27 '13 at 17:01
  • Is that fine this way? – Sebastian Hoffmann Nov 27 '13 at 17:05
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)
mort
  • 12,988
  • 14
  • 52
  • 97