Рассмотрим следующий пример ( snippet (0) ):
struct X
{
constexpr int get() const { return 0; }
};
void foo(const X& x)
{
constexpr int i = x.get();
}
int main()
{
foo(X{});
}
Приведенный выше пример компилируется со всеми версиями g++
до g++ 10.x
и никогда не компилируется в clang++
. Сообщение об ошибке:
error: 'x' is not a constant expression
8 | constexpr int i = x.get();
|
живой пример на godbolt.org
Ошибка имеет смысл , поскольку x
никогда не является константным выражением в теле foo
, однако:
Это становится еще интереснее, когда я отмечаю X::get()
как static
( (на кресте). org) фрагмент (2) ). С этим изменением все протестированные версии g++
(включая транк) компилируются, в то время как clang++
по-прежнему не всегда компилируется.
Итак, мои вопросы:
Правильно ли g++ 9.x
принять фрагмент (0) ?
Правильно ли все компиляторы принимают фрагмент (1) ? Если да, то почему ссылка значима?
Правильны ли g++ 9.x
и g++ trunk
при принятии фрагмента (2) ?