I'm interested to know why the second static_assert
in my code below doesn't work. It seems like even though the array c
is a reference to a
, the size of the array is embedded in the type, so it should be available at compile time.
#include <array>
int main()
{
std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
std::array<int,2>& c = a;
static_assert(a.size() == b.size(), "a.size==b.size"); // ok size of array is compile time constant
static_assert(c.size() == a.size(), "c.size==a.size"); // compiler error "static_assert expression is not an integral constant expression"
}
c. The size of an array is determined at compile time. Hence, the given statement is “True”. The size of an array is determined at compile time.
std::array is a container that encapsulates fixed size arrays. This container is an aggregate type with the same semantics as a struct holding a C-style array T[N] as its only non-static data member. Unlike a C-style array, it doesn't decay to T* automatically.
yes it works in gcc, my doubt was why it works but it seems now newer version of C allows this as pointed out by others..
std::array provides many benefits over built-in arrays, such as preventing automatic decay into a pointer, maintaining the array size, providing bounds checking, and allowing the use of C++ container operations.
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 c
or 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");
}
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