Базовая проблема не связана непосредственно с ослабленными правилами constexpr, функция constexpr является только постоянным выражением, если аргументы являются постоянными выражениями. В вашем втором случае:
int array[std::max(1,2)];
Это работает, потому что целочисленные литералы - это действительно постоянные выражения.
C++ 11 более конкретно в данном случае, проект C++ стандарт 11 в разделе 5.19
[expr.const] излагает случаи, когда суб-выражение не считается постоянным выражением и содержит следующее:
призывание функции constexpr с аргументами, что, когда замещенный вызов функции замещения (7.1.5), не производят постоянное выражение;
в C++ 14 этот пункт был удален, и мы имеем следующее исключение:
призывание функции, кроме конструктора constexpr для буквального класса, функции constexpr, или неявный вызов тривиального деструктора (12.4) [Примечание: разрешение перегрузки (13.3) равно , применяемое, как обычно, - примечание);
, и мы должны использовать остальные правила относительно аргументов (подвыражения).
В первом случае:
int array[std::max(a.size(), b.size()];
std::vector::size не отмечена constexpr и поэтому она подпадает под процитированным выше исключением.
Также отметим, что в разделе 7.1.5
[dcl.constexpr] мы имеем следующее:
Вызов функции constexpr производит тот же результат, как призыв к эквивалент не-constexpr функции в во всех отношениях, за исключением того, что вызов функции constexpr может появляться в постоянном выражении.
Передача аргументов функции constexpr, которые не являются постоянными выражениями, означает, что выражение не доступно для использования в контекстах, для которых требуется постоянное выражение.
Как DYP указывает на то, что std::max
не было сделано constexpr в 11 из-за к различным вопросам, C++, вероятно, в том числе комитет является консервативным и ограниченное время, мы можем увидеть некоторые из вопросов, связанных с N3039. это забывается см N3856, который говорит:
Эта короткая статья предлагает сделать стандартные функции минимального и максимального constexpr. Они были сверху в списке мотивирующих случаев для al- , ссылающихся на опорные параметры для функций constexpr в C++ 11. Они были забыты после изменения основного языка было принят
Для справки мы знаем, что 1
и 2
постоянно выражение из раздела 5.19
, который говорит:
Буквальная константа является постоянным выражением prvalue ядра тип литерала, но не тип указателя. Интегральное постоянное выражение является литераловым постоянным выражением целочисленного или неперечисленного типа перечисления. [...]
'constexpr' здесь не означает, что возвращаемое значение функции является' constexpr'. Это означает, что функция 'constexpr'. (Подобно тому, как 'static int x();' не означает, что 'x' возвращает статический int). –