3

Suppose I have the class

template<class T>
class Vector
{
  public:
    Vector() = default;

    inline size_t size() const { return _vector.size(); }

  private :
    std::vector<T> _vector;
};

Is there any way to delegate functions (or operators) to _vector, at compile time, without overhead ?

I can of course (and it's what I'm doing) forward everything by declaring every functions I need, and just call the appropriate function to the member, as I did with size().

This article propose exactly what I would need. For example using this :

template<class T>
class Vector
{
  public:
    Vector() = default;

  private :
    std::vector<T> _vector;

  public:
    using _vector {
      size_t size() const;
      void push_back(const T&);
    }
};

The compiler would then generate the appropriate code. But I didn't find anything like this, is it possible ?

Pluc
  • 901
  • 8
  • 21
  • I think I'm gonna suffer for mentioning it, but it's possible with private inheritance & using... – MFH Dec 04 '12 at 09:16
  • 1
    Your inlined function likely *will* forward at compile time without any overhead. The proposed shorthand for forwarding didn't make it into the standard, so you will have to do it by hand. – Bo Persson Dec 04 '12 at 09:17
  • @BoPersson Yes, I just wanted a lazy way to do it without writing it :) – Pluc Dec 04 '12 at 09:20

1 Answers1

2

First way: You can inherit std::vector<T> publicly to make such delegation possible:

template<class T>
class Vector : public std::vector<T>
...

Whether to inherit std::vector or not is little debatable, but then it's your code.

Second way: If you are particular about the composition then make Vector<T> objects behave as smart pointers:

template<typename T>
class Vector
{
  std::vector<T> _vector;    
public:
  std::vector<T>* operator -> () { return &_vector; }
};
Vector<int> vi;
vi->size(); // instead of vi.size()

Third way: Overload operator () for syntactic sugar:

template<typename T>
class Vector
{
  std::vector<T> _vector;
public:
  std::vector<T>& operator ()() { return _vector; }
  const std::vector<T>& operator ()() const { return _vector; }
};
Vector<int> vi;
vi().size(); // instead of vi.size()
Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • I wanted to avoid inheritance. I like other solutions. What would be the syntax to call `operator[]` with the second one ? Any drawbacks for those solutions ? – Pluc Dec 04 '12 at 09:47
  • @ThePluc, 2nd solution is not that much effective alone. You may have to overload `operator *()` also to make it complete. BTW, why do you want to avoid inheritance ? – iammilind Dec 04 '12 at 09:53
  • Because I used this simple example to explain what I wanted, but the real class would be a true composition with different members, also containers are not designed to be inherited (I saw your link :p). I'll use the `operator()` after checking if that's ok for me, otherwise I'll just declare by hand. I think the syntax for the second solution might be misleading, especially if working with a pointer. – Pluc Dec 04 '12 at 10:07
  • Just to say I accepted this as the answer since it provides an alternative with a simple syntax. The real answer is that it's not possible at the moment though :) – Pluc Dec 04 '12 at 10:18