I am writing a std::array
class as a little exercise, during which I found out that std::array
does not implement operator->
.
Thus for arrays the following is allowed
struct S { int s; };
S c[2];
c->s = 2;
but for std::array
this is not possible
struct S { int s; };
std::array<S,2> cpp;
// cpp->s = 2; // does not compile
which makes a std::array
not fully compatible to a C-array.
Is there a reason for this decision.
(I expected harsh reactions, but I am surprised how fast they came.)
Clearly, as we know, arrays are not pointers but just decay to them. The problem in C++ is not that they decay, but that they decay automatically. If one on purpose uses ->
syntax for a std::array
, this is most likely bad design, but not a problem.
Even with an operator->
the std::array
would be something like a first-class-citizien in C++ (which is an array not).
C++ is not a language where the user shall be prevented from every harm.
c->s
works because a raw array like c[2]
, automatically decays to a pointer in expressions.
So c->s
is equivalent to c[0].s
.
An object such as std::array
does not decay to a pointer and provides no ->
or T*
overloads, hence cpp->s
does not work.
std::array
[is] not fully compatible to a C-array
Fortunately not! It's an array-like object that solves many issues associated with raw arrays.
Accessing the array's first element like c->s
might be nice and concise, but readability of it is questionable, in fact many people consider array decay a problem rather than a feature.
Also CppCoreGuidelines admits array-to-pointer-decay is a problem area:
Ideally, a program would be completely statically (compile-time) type safe. Unfortunately, that is not possible. Problem areas:
- unions
- casts
- array decay
- range errors
- narrowing conversions
std::array
addresses the idiosyncrasy stemming from C, by prohibiting it.
C++ is not a language where the user shall be prevented from every harm ...
True. As they say, "when your hammer is C++, everything becomes a thumb".
But this doesn't mean we can't do anything about it, one problem area at a time. This is what std::array
does to raw arrays, std::unique_ptr
to owning pointers, nullptr
to NULL
, etc.