Почему constexpr требуется, хотя функция-член constexpr?

Следующее не компилируется, если я не поставил constexpr перед initializer_list:

constexpr std::initializer_list<int> il = {
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
std::array<int, il.size()> a;

Но размер initializer_list - constexpr:

constexpr size_type size() const;

Ответы

Ответ 1

std::initializer_list<int> il = rand() ? std::initializer_list<int>{1}
                                       : std::initializer_list<int>{1,2,3};

std::array<int, il.size()> a;

Вот почему.

A constexpr Функция-член - это функция, которая может выполняться в пределах константного выражения, она не обязательно дает результат, который является константой времени компиляции. Например:

struct S
{
    int m;
    constexpr int foo() const { return m; }
};

S s{rand()};
int j = s.foo();     // only known at run-time

constexpr S cs{42};
int arr[cs.foo()];   // compile-time constant

Ответ 2

Написав std::array<int, il.size()> a;, вы утверждаете, что il.size() можно оценить во время компиляции с постоянным результатом, разрешив создание шаблона.

Итак, как метод initializer_list::size(), так и ваша переменная il должны быть объявлены как constexpr.