Use array instead of vector

C++20 provides std::span, which is a more flexible way to pass around a view to a contiguous memory range than alternatives like a pointer and a size, or a std::vector &.

When adopting this pattern I would like to also be able to automatically find cases where the underlying range that gets passed around can be changed from std::vector to std::array, which avoids the need for memory allocation.

Motivation is this: We have a system where we receive data from a socket during normal operation. This data gets fed into a std::vector at some point, and then we pass that range into the application logic, which makes sense when we have a protocol that effectively is treated as a list of int. For test code, we can very often pass a range of int directly into the same machinery, without needing to put it into a std::vector first, because at each call site we are applying a specific message, which a compile time known size.

There’s a lot of these, and using a static analysis tool to find cases would help a lot in terms of the migration process. The idea is that std::vector gets created in a way where the size is constant and would be known at compile time, and only gets used in a way where it could be replaced with a std::array, like creating a std::span from it.

Hi @torgeir.skogen,

I see two difficulties with such a rule:

  • I think that std::array should definitively be preferred to std::vector when the constness of the size is part of the domain, not something incidental. A barcode of 10 digits should use an array. 10 test cases sent to an algorithm don’t really have to. The fact that a size is not changed in the existing code does not mean that the size is meant to be constant.

  • std::array is not as flexible as std::vector for initialization. You cannot write: std::array<int> a {1,2,3}; and let the compiler deduce the size.

I created [CPP-4049] - Jira to keep track of this rule idea.

These points are true, but there are ways to work around some of the limitations. It’s possible to use std::to_array to make an array of an explicitly specified type while having the size of the array be deduced from the arguments. Otherwise, if the type is the same as all the argument, class template argument deduction is also an option.

You’re right about std::to_array, starting with C++20.