C++ code that compiles in gcc 9.3 but not in gcc 10.2

Viewed 207

The following code compiles in gcc 9.3, but not in gcc 10.2:

constexpr std::array<int, 2> opt = {1,2};          

template <typename T>
constexpr auto f(const T& arr) 
{
    std::array<int, arr.size()> res{};
    return res;
}

int main()
{
    auto res = f(opt);
 
}

The code is in https://godbolt.org/z/8hb6M8.

The error given by gcc10.2 is that arr.size() is not a constant expression.

Which compiler is right? 9.3 or 10.2?

If 10.2 is right, how can I define a compile time array and pass its size (and the array) as an argument?

3 Answers

Not sure which one is right but for

how can I define a compile time array and pass its size (and the array) as an argument?

You can change the function to

template <typename T, std::size_t N>
constexpr auto f(const std::array<T, N>& arr) 
{
    std::array<int, N> res{};
    return res;
}

and now the size gets uplifted into the template parameter.

Another alternative which works in both compilers and doesn't require changing the template declaration:

std::array<int, std::tuple_size_v<T>> res{};

The definition of constant expressions has been changed since C++20, you can find several changes on this.

The shorter answer is to change your function signature:

template <typename T>
constexpr auto f(const T& arr);

into:

template <typename T>
constexpr auto f(const T arr);

Then it works.

Related