That static_assert will kick in only if the function is called:

#include <assert.h>
#include <cstdlib>

template <std::size_t Idx, typename T, std::size_t N>
constexpr T& get(T (&arr)[N]) noexcept {
    static_assert(Idx < N, "Index out of bounds");
    return arr[Idx];
}

int main(void) {
    constexpr int arr[99] = {1, 2, 3, 4};
    static_assert(get<2>(arr) == 3);

    typedef decltype(&get<99>(arr)) wtf;
    wtf p = &get<2>(arr);  // works
}

C++20 requires variant is better.

DBJ

On Tue, 1 Mar 2022 at 17:39, Arthur O'Dwyer via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Tue, Mar 1, 2022 at 11:34 AM Barry Revzin <barry.revzin@gmail.com> wrote:
On Tue, Mar 1, 2022 at 9:59 AM Arthur O'Dwyer via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Tue, Mar 1, 2022 at 10:13 AM Nikolay Mihaylov via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Once again, why do we need the size?
Shall we check the size?
Via static_assert?
During runtime?

In the proposed std::get for C arrays, AIUI, the size would be part of the signature. It would look like this:

template<size_t X, class T, size_t N> requires (X < N)
constexpr T& get(T (&arr)[N]) noexcept {
    return arr[X];
}

No, it wouldn't. Paulo's email contained the correct implementation:

template <std::size_t Idx, typename T, std::size_t N>
constexpr T& get(T (&arr)[N]) noexcept
{
    static_assert(Idx < N, "Index out of bounds");
    return arr[Idx];
}

This would match what std::get does for std::array, std::pair, and std::tuple.

Oh, gross. If it's not going to be SFINAE-friendly, then I don't particularly have an opinion what it does.

–Arthur
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals