0

I implemented SpareArray class. It's a big one, so there is no sense to show it all, but what is important is that is has insert method, which makes it possible to insert values at any index (from zero to "infinity"). So, my client code may look like so:

auto arr = new SpareArray<int>{};
arr.insert(100, 1);

The above code inserts value 1 at index 100. Now, I want to be able to use square brakets notation to get the same result:

auto arr = new SpareArray<int>{};
arr[100] = 1; //I want this line to internally call arr.insert(100, 1);

So, how can operator[] be difined to internally call insert method? I need this call, because insert method has some business logic and I want this business logic to take place also in this case (in case of []).

Jacobian
  • 10,122
  • 29
  • 128
  • 221

1 Answers1

1

You can return a proxy that does the final call to insert and acts as a wrapper around an element of your array.

template<typename T>
struct Proxy {
  Proxy(SpareArray<T> &This, std::size_t Index) : This(This), Index(Index) {}

  T &operator=(const T &Value) {
    This.insert(Index, Value);
    return This.get(Index); // or however you get an element
  }

  operator T&() { return This.get(Index); }
  operator const T&() const { return This.get(Index); }

private:
  SpareArray<T> &This;
  std::size_t Index;
};

For simplicity, I didn't add more but I would expect such a class to have proper noexcept semantics and a move assignment operator, for example. You also might want to make sure that you delete the copy constructors and such.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • 1
    Thank you, sir! I got the idea and will check it. – Jacobian Feb 04 '18 at 11:31
  • Would you be so kind to show how this proxy can be used inside some arbitrary class `SpareArray`? Just an idea would be enough. Now when I try to make it a friend class inside SpareArray and return it from operator[] override, I get a ton of error messages. – Jacobian Feb 04 '18 at 12:18
  • @Jacobian Why does the proxy have to be a friend? What are the error messages? I can only guess because there are lots of things that could be wrong. – Rakete1111 Feb 04 '18 at 13:04
  • I will address it in a new question, that I'm just about to ask at SO. – Jacobian Feb 04 '18 at 13:06
  • If you have some time, please, have a look - https://stackoverflow.com/questions/48608414/templated-proxy-design-pattern – Jacobian Feb 04 '18 at 13:13
  • Sorry for bothering you once again. I have a tiny question. Now, this construct started to work: `auto arr = new SpareArray{}; arr[100] = 1;`. But this one stopped working - `std::cout << arr[100] << std::endl;`. Even though, my `SpareArray` class has such an overload: `T const& operator[] (int index) const {...}`. It seems like compiler still calls here proxied version of `operator[]`. Probably, you know what may be wrong with that. – Jacobian Feb 04 '18 at 14:37
  • @Jacobian Do what I did, because it seems like you didn't: Always return the proxy object, and provide a conversion operator inside the proxy object so that it implicitly converts itself to the element. – Rakete1111 Feb 04 '18 at 14:40