Search code examples
c++stdarray

Why there is no operator-> in std::array


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.


Solution

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