Size of reference to std::array not available at compiletime

the size of the array is embedded in the type, so it should be available at compile time.

This is true. But regardless, c is not a constant expression and therefore expression that contains it as a subexpression cannot be a constant expression - except certain operators that interact only with the type of the operand such as sizeof.

You can get the size for example using:

static_assert(
    std::tuple_size<
        std::remove_reference_t<decltype(c)>
    >::value == a.size(),
    "c.size==a.size"
);

Unfortunately, it is not very pretty.


Note, that if you move all declaration out of main function, code would compile. Why? Because a is automatic variable, so it's not really a compile time object and reference is not elided here, therefore neither a nor cor c.size() are constexpr. For global variables location of a can be determined at compile time.

IF you try bind them within function like this:

constexpr std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
constexpr const std::array<int,2>& c = a;

You'll get error that a is not a constant expression. Variant which still may compile:

#include <array>

std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};

int main()
{
    std::array<int,2>& c = a;

    static_assert(a.size() == b.size(), "a.size==b.size"); 
    static_assert(c.size() == a.size(), "c.size==a.size"); 
}