Этот код прекрасно компилируется на всех больших 4-х компиляторах, даже на -pedantic
struct S
{
constexpr S(int a) {}
};
constexpr int f(S a)
{
return 1;
}
int main()
{
int a = 0;
S s(a);
constexpr int b = f(s);
}
Тем не менее, это не должно быть так в соответствии со стандартом... верно? Во-первых, s
нельзя будет использовать в константных выражениях [expr.const]/3, потому что он не соответствует критериям либо constexpr
, либо const
и перечисления или интегральный тип.
Во-вторых, он не инициализирован константой [expr.const]/2, поскольку полное выражение инициализации не будет константным выражением [expr.const]/10 из-за Преобразование lvalue в rvalue выполняется для переменной (a
), которую нельзя использовать в константных выражениях при инициализации параметра конструктора.
Все ли эти компиляторы просто исключают инициализацию параметра конструктора, потому что он не имеет побочных эффектов и соответствует ли он стандарту (я уверен, что это не так на 99%, так как единственный способ это сделать - это сделать s
constexpr
и передать ему const int
или int
, который объявлен constexpr
)?