std::vector with custom growth factor So, yes, I know that "you shouldn't derive from std containers" but by now it's more of philosophical rule in my mind than a technical one. I've googled again for the one fundamental reason one should never-ever-ever-ever-do-that-ever-ever-ever-or-you-die but couldn't find it.

So, if there's nothing fundamentally wrong with the following and if we set aside performance considerations, can I a get a plain-old code review of this:

namespace growth
{
    template&lt;size_t N&gt;
    class linear
    {
    public:
        static_assert(N != 0, "Linear growth requires positive factor");

        static size_t grow(size_t size, size_t capacity)
        {
            return (size == capacity) ? capacity + N : capacity;
        }
    };

    template&lt;typename Ratio = std::ratio&lt;2, 1&gt;&gt;
    class geometric
    {
    public:
        static_assert(Ratio::num &gt; Ratio::den, "Geometric growth requires ratio greater than 1");

        static size_t grow(size_t size, size_t capacity)
        {
            return (size == capacity) ? std::max((size_t)(capacity * (Ratio::num / (double)Ratio::den)), capacity + 1) : capacity;
        }
    };
}

template&lt;typename T, typename Growth, class Allocator = std::allocator&lt;T&gt;&gt;
class custom_growth_vector : public std::vector&lt;T, Allocator&gt;
{
public:
    using vector = std::vector&lt;T, Allocator&gt;;

    using vector::vector;

    void push_back(T&amp;&amp; value)
    {
        vector::reserve(Growth::grow(vector::size(), vector::capacity()));
        vector::push_back(value);
    }

    // Also replace emplace_back, insert, etc.
};

// ...

// Grows by 50% rather than double when size == capacity.
custom_growth_vector&lt;int, growth::geometric&lt;ratio&lt;3, 2&gt;&gt;&gt; cgvi;
Let's start with an attempt at a short summary of the situation with inheritance.

As long as you just create/use/destroy an object of your type, the fact that it inherits publicly from a standard container doesn't lead to a problem.

The problem arises if you have pointer (or reference) to the base class that refers to an object of the derived class, and you destroy the object via that pointer to base.

std::vector&lt;int&gt; *t = new custom_growth_vector&lt;int, growth::geometric&lt;ratio&lt;3, 2&gt;&gt;&gt;;

// ...

delete t; // This causes undefined behavior


Unfortunately, there's nothing you can do in your class to prevent this--part of the definition of public inheritance is that it allows implicit conversion to the base class.

Aside from that:

Linear growth

Using your growth::linear class means that any vector you create this way no longer meets the requirement for push_back to have amortized-constant complexity. In the other direction, this does mean the amount of space that's "wasted" by growing the vector is limited to a constant.

push_back

push_back normally has overloads for both const lvalue reference, and rvalue reference, though this may just be another member function you haven't provided (yet).

Growth Factor

I guess the biggest problem I see in the end is the fairly simple question what the real point of this is supposed to be. Most systems use virtual memory, which typically means that even if you think you're expanding an allocation following a geometric series, chances good that the system will allocate actual storage for your data following an arithmetic series, almost regardless of what you try to do.