0

I want a class derived from std::vector for my operator []

template<class T>
class MyVector : public std::vector<T>
{
public:
    // ?...

    const T &operator[](size_t index) const
        {
            //...
        }

    T &operator[](size_t index)
        {
            //...
        }
};

int main()
{
    MyVector<int> myVec = { 1, 2, 3 };
    //...
}

How can I do this deriving all std::vector constructors and assigning operators for C++11?

Ufx
  • 2,595
  • 12
  • 44
  • 83
  • 2
    FYI: publicly Inheriting from `std::vector<>` is super dangerous as it doesn't have a virtual destructor. –  Jul 05 '18 at 15:06
  • What if I add `virtual ~MyVector() {}` – Ufx Jul 05 '18 at 15:09
  • 2
    that doesn't change anything. As long as `std::vector* x = new MyVector();` is possible, you'll be in trouble. Addind a virtual destructor to `MyVector` doesn't change anything about what a pointer to a `std::vector<>` means. –  Jul 05 '18 at 15:11
  • Are there ways to make this deriving not dangerous? – Ufx Jul 05 '18 at 15:13
  • 2
    use private or protected inheritance, and make methods available publicly with using declarations. –  Jul 05 '18 at 15:15
  • 1
    You probably shouldn't be using inheritance *at all*. What's in the `// ?...` that warrants *expanding* the interface of `vector`? – Caleth Jul 05 '18 at 15:21
  • @Frank It is stupid 99% of the time to `new` a `std::vector` so it is far less dangerous than it could be. – Yakk - Adam Nevraumont Jul 05 '18 at 18:02

1 Answers1

2

Usually this is a bad idea.

First, because if someone was as silly as to new MyVector<int> and then store that in a std::vector<int> and then delete through that pointer, you have UB. But that is a pretty stupid use case; using new on std::vector is really bad code smell.

Second, because it seems pointless and confusing.

But you can do it.

template<class T>
class MyVector : public std::vector<T>
{
public:
  using std::vector<T>::vector;
  using std::vector<T>::operator=;
  MyVector(MyVector const&)=default;
  MyVector(MyVector &&)=default;
  MyVector& operator=(MyVector const&)=default;
  MyVector& operator=(MyVector &&)=default;
  const T &operator[](size_t index) const
    {
        //...
    }

T &operator[](size_t index)
    {
        //...
    }
};

now, this doesn't support construct-from std::vector<T>.

MyVector( std::vector<T>&& o ):std::vector<T>(std::move(o)) {}
MyVector( std::vector<T> const& o ):std::vector<T>(o) {}
MyVector& operator=( std::vector<T>&& o ) {
  static_cast<std::vector<T&>>(*this) = std::move(o);
  return *this;
}
MyVector& operator=( std::vector<T> const& o ) {
  static_cast<std::vector<T&>>(*this) = o;
  return *this;
}

that covers some last cases.

This won't be completely transparent, but it covers 99.9% of cases.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524