This is a good example of when it's both reasonable and useful to inherit from std::vector, providing:
you can be sure they won't be deleted using a pointer to their vector base class (which would be Undefined Behaviour as the vector destructor's not virtual)
you're prepared to write a forwarding constructor or two if you want to use them
ideally, you're using this in a relatively small application rather than making it part of a library API with lots of distributed client users - the more hassle client impact could be, the more pedantic one should be about full encapsulation
template <typename T, size_t Y, size_t Z>
struct Vec_3D : std::vector<std::array<std::array<T, Y>, Z>>
{
T& operator(size_t x, size_t y, size_t z)
{
return (*this)[x * Y * Z + y * Y + z];
}
const T& operator(size_t x, size_t y, size_t z) const
{
return (*this)[x * Y * Z + y * Y + z];
}
};
So little effort, then you've got a nicer and less error prone v(a, b, c) notation available.
Concerning the derivation, note that:
(The lack of data members / extra bases means even slicing and accidental deletion via a vector* are likely to work in practice, even though they should be avoided it's kind of nice to know you're likely playing with smoke rather than fire.)
Yes I know Alexandrescu, Sutter, Meyers etc. recommend not to do this - I've read their reasons very carefully several times and if you want to champion them even for this usage, please bring relevant technical specifics to the table....