Is there any practical difference between
std::array<const T, N>
and
const std::array<T, N>
?
It looks that non-const array holding const elements is still not able to be swapped, assignment operator is not working either.
When should I prefer one over another?
#include <array>
std::array<const int, 5> array_of_const = {1,2,3,4,5};
std::array<const int, 5> array_of_const2 = {1,2,3,4,5};
const std::array<const int, 5> const_array = {1,2,3,4,5};
const std::array<const int, 5> const_array2 = {1,2,3,4,5};
int main()
{
// Assignment doesn't work for either
array_of_const = array_of_const2;
const_array = const_array2;
// Swapping doesn't work for either
array_of_const.swap(array_of_const2);
const_array.swap(const_array2);
// Indexing...
array_of_const[0] = 0;
const_array[0] = 0;
return 0;
};
CodePudding user response:
Copies of std::array<const T, N> are still "logically const", whereas by default a copy of const std::array<T, N> is mutable. If allowing or preventing that matters to you, one is preferable to the other.
There are differences in what templates they match, e.g. the case in Ilya's answer.
CodePudding user response:
there could be at least one difference - case when you need to pass variable to some other function, for example:
#include <array>
std::array<const int, 5> cc_arr5 = {1,2,3,4,5};
const std::array<int, 5> cc_arr5_2 = {1,2,3,4,5};
template<class T, std::size_t N>
void func(std::array<T, N>& a) {
// do not change a, for example just calculate sum
}
int main()
{
func(cc_arr5);
func(cc_arr5_2); // this line does not compile
return 0;
};
CodePudding user response:
They are indeed different types, so you cannot use one in a place whether the other would be expected, for example in a function call or an assignment.
That being said, as an array is a fixed size container with no auxiliary data member, having the container const prevent any change to its elements and having the elements const does not allow any change to the container since it obviously has no other data member.
Said differently both types will have the very same valid and invalid operations.
The main difference I can think about, is the const_cast implication: an array can be (implicitly) converted to a const array of the same element type but not to an array of the const modified type:
std::array<int, 3> a {1, 2, 3};
std::array<const int, 3> b = a; // Error: no known conversion from 'array<int, [...]>' to 'const array<const int, [...]>
const std::array<int, 3> c = a; // Ok
