Могут ли временные привязки связываться с неконстантными ссылками?
Я написал следующий код, чтобы проверить это:
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&)’