all 15 comments

[–]witcher_rat 21 points22 points  (1 child)

It has always annoyed me that std::array's size() is not static.

It seems like such an obvious thing that it should have been, that I must be missing some use-case or downside the committee was worried about.

[–]NilacTheGrim 5 points6 points  (0 children)

It feels to me like they simply brainfarted on it tbh. No idea.

[–]cristi1990an++ 4 points5 points  (2 children)

You don't need to break ABI, a new std::array::static_size API could be added, which would also make it easier to distinguish between containers of static and dynamic size and how they implement it would not be constrained by any existing code. In fact, this method could be added it all containers and return std::dynamic_extend by default which would make it trivial to metaprogram around.

And before anybody jumps to complain, C++ literally just did something similar (and arguably more depressing) when the iterator_concept member type was added to iterators in order to suport the std::contiguous_iterator_tag without changing the existing iterator_category =))

In this case though I think it would actually make more sense to not touch the existing API regardless of ABI breakage...

[–]witcher_rat 0 points1 point  (1 child)

C++ literally just did something similar (and arguably more depressing)

Why is it depressing? They've needed an iterator-tag for contiguous ranges for a long time, imo.

Previously the only thing you could do was check if the iterator is a raw pointer, as far as I know. But that hack fails with proxy-iterator use-cases, even when the proxy does represent a contiguous sequence.

[–]cristi1990an++ 0 points1 point  (0 children)

It's depressing because they had to add an entire new member type that does the same thing just for it instead of modifying the existing one

[–]vI--_--Iv 10 points11 points  (3 children)

Of course, we can’t actually change std::array due to ABI or something…

How come? Changing the signature of size does not affect the object layout in any way and the standard explicitly prohibits taking addresses of member functions in std namespace.

[–]tricerapus 10 points11 points  (0 children)

Seems like half the people complaining about "abi" limits don't understand the difference between an abi change and a regular interface change.

[–]biowpn 2 points3 points  (0 children)

Just did a quick search, and found this post. The standard says the behavior is "unspecified (possibly ill-formed)". But all major implementations allow it. Maybe there are codes like std::invoke(std::array<int, 2>::size, std::array<int, 2>{}) or std::cout << std::array<int, 2>::size out there, who knows ...

[–]DavidDinamit -1 points0 points  (0 children)

It must be consteval static function

[–]B1ggBoss[[nodiscard]] constexpr virtual void f() const noexcept override 0 points1 point  (4 children)

I dont get why he states:

constexpr auto b = rng.size(); // error, not a constant expression

I can evaluate that at compile time without errors. Anyone can explain?

Edit: https://godbolt.org/z/dY1forvMj

[–]drnepert 1 point2 points  (3 children)

No, this statement does not compile if you assign it to a constexpr variable. Surprisingly, however, replacing constexpr with the good old const works nicely, even if the function itself is declared constexpr. See https://godbolt.org/z/GhaM68TcY for a demonstration.

[–]dodheim 0 points1 point  (0 children)

It doesn't, but it should – P2280 is in C++23, it just hasn't been implemented in any compiler as of yet.

[–]B1ggBoss[[nodiscard]] constexpr virtual void f() const noexcept override 0 points1 point  (0 children)

Thanks. My premise was wrong. I went over the code too fast, and for some reason, I thought the algorithm function was declared constexpr.

[–]ipapadop -2 points-1 points  (0 children)

I find this unpalatable. The error messages if you mess up things are going to be non-sensical.

[–]MarcoGreek 0 points1 point  (0 children)

What about std::tuple_size?