Могут ли временные привязки связываться с неконстантными ссылками?

Я написал следующий код, чтобы проверить это:

struct X
{
   char* x;
   X()
   {
      x = new char('a');
   }
   ~X()
   {
      *x = 'b';
      delete x;
   }
};

void foo(const X& x)
{
}
void goo(X& x)
{
}

int main()
{
   foo(X());
   goo(X());
}

Деструкторы для временных вызываются после выхода из обеих функций, но я думал, что вы можете привязать только временную к const ссылка. Почему goo работать тогда?

Это UB и MSVS не так, или это нормально?

2 ответа

Решение

Это незаконно. Соответствующая реализация диагностирует это (то есть, по крайней мере, должна предупредить), но MSVC++ допускает это как расширение.

Или ошибка, если вы недобры, но IIRC причина, по которой они все еще это допускают, по долгосрочным унаследованным причинам: номинально для поддержки кода, написанного для MSVC++ до того, как C++ был стандартизирован, но, конечно, как только вы позволяете людям писать это, они пишут это случайно в новом коде тоже, так что наследие живет. Если это преднамеренно, то это (неправильная) функция, а не ошибка, верно? В любом случае, для диагностики неправильно сформированных программ требуется соответствующая реализация, поэтому, если вы не получите предупреждение, компилятор не будет соответствовать.

Это, очевидно, расширение MS. Например, в GCC 4.3.4 он не компилируется со следующим сообщением:

prog.cpp: In function ‘int main()’:
prog.cpp:25: error: invalid initialization of non-const reference of type ‘X&’ from a temporary of type ‘X’
prog.cpp:18: error: in passing argument 1 of ‘void goo(X&)’
Другие вопросы по тегам