Alex B.
Alex B.

Reputation: 368

Three-dimensional array as a vector of arrays

I have 3-dim double array with two of its dimensions known at compile time. So to make it efficient, I'd like to write something like

std::vector<double[7][19]> v;
v.resize(3);
v[2][6][18] = 2 * 7*19 + 6 * 19 + 18;

It's perfect except it does not compile because of "v.resize(3);" Please don't recommend me using nested vectors like

std::vector<std::vector<std::vector<double>>> v;

because I don't want to set sizes for known dimensions each time I extend v by its first dimension.

What is the cleanest solution here?

Upvotes: 1

Views: 131

Answers (2)

Tony Delroy
Tony Delroy

Reputation: 106236

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:

  • your derived type makes no attempt to enforce different invariants on the object

  • it doesn't add any data members or other bases

(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....

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409442

Why not a std::vector of std::array of std::array of double?

std::vector<std::array<std::array<double, 19>, 7>> v;

Upvotes: 3

Related Questions