This is a good old C array:
int a[10];
And this is a good old C array that is const
:
const int b[10];
In C++, there seem to be two ways to define std::array
s that are const
:
std::array<const int, 10> c;
const std::array<int, 10> d;
Are these two definitions equivalent? If so, what is the idiomatic one? If not, what are the differences?
Well, the original const int b[10];
is only useful when you can initialize the array, so both of the std::array
examples don't work in practice.
std::array<const int, 10> c;
This is the closest to const int c[10];
. The problem is there will be no default constructor for it, and because the elements are not mutable, it's worthless to use this. You must provide some initialization for it in the constructor. As-is, it will give a compiler error because the default constructor did not initialize the elements.
This code means that c
is mutable, but the elements themselves are not. In practice, however, there are no mutations on c
that don't affect the elements.
const std::array<int, 10> d;
This means d
is not mutable, but the elements are of mutable type int
. Because const
will propagate to the members, it means the elements are still not mutable by the caller. Similar to the above example, you will need to initialize d
because it's const
.
In practice, they will both behave similarly with respect to mutability, because mutable operations on array
always touch the elements.
They aren't equivalent -- c.reference
is int&
whereas d.reference
is const int&
(not that you can use that syntax to access typedefs, but you could capture the type by template argument deduction and tell the difference).
But I'm pretty sure tenfour has the key observation, "there are no mutations on c
that don't affect the elements". So as far as anything you actually do to the arrays is concerned they're the same, they just have different meta-data because of their different types.
The main case I can think of where it would make a difference is if you use the type itself in an interface (as opposed to taking an iterator or range template parameter). I'd say that when taking it as a pointer or reference parameter you should const-qualify the array
type itself, since it costs you nothing and allows the caller to use your function whichever choice they made. You may const-qualify the element type, but whichever one you use is incompatible with the other one, so basically everyone has to agree which to use or else there will be some copying required. That requires active co-ordination as to style, I think, since I doubt that you'll get everyone in the world to agree which is best. const int
probably has the better case, on the principle that you should const
everything you can, but I expect int
is what people will use who haven't thought about it at all, since they're used to all those C++03 containers that can't have a const
value type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With