char f1();
void f2(char&);
struct A {};
A f3();
void f4(A&);
int main()
{
f2(f1()); // error C2664. This is as expected.
f4(f3()); // OK! Why???
}
ошибка C2664: ‘void f4 (char &) ‘: невозможно преобразовать аргумент 1 из’ char ‘
чар &’
Меня учили, что в C ++ неконстантный ссылочный параметр не может быть привязан к временному объекту; и в коде выше, f2(f1());
вызывает ошибку, как и ожидалось.
Однако почему это правило не применяется к строке кода f4(f3());
?
PS: Мой компилятор VC ++ 2013. Даже если я прокомментирую строку f2(f1());
затем код, содержащий f4(f3());
будет скомпилирован без каких-либо ошибок или предупреждений.
Обновить:
MSDN говорит:
В предыдущих выпусках Visual C ++ неконстантные ссылки могли быть
привязан к временным объектам. Теперь временные объекты могут быть связаны только
чтобы констатировать ссылки.
Так что я думаю, что это ошибка VC ++. Я отправил отчет об ошибке Команда VC ++
Если вы компилируете с опция / Za чтобы отключить языковые расширения, компилятор отклоняет оба вызова:
> cl /Za test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(11): error C2664: 'void f2(char &)' : cannot convert argument 1 from 'char' to 'char &'
test.cpp(12): error C2664: 'void f4(A &)' : cannot convert argument 1 from 'A' to 'A &'
A non-const reference may only be bound to an lvalue
Существует несколько (очень ограниченных) обстоятельств, при которых компилятор с включенными языковыми расширениями по-прежнему позволяет неконстантной ссылке lvalue связываться с выражением rvalue. Насколько я понимаю, это в значительной степени позволяет избежать взлома нескольких огромных унаследованных кодовых баз, которые полагаются на это «расширение».
(Как правило, использование / Za не рекомендуется по многим причинам, но в основном из-за того, что заголовки Windows SDK не могут быть # включены с параметром / Za.)
Ваш компилятор не соответствует стандарту (может быть, это документированное расширение компилятора?). GCC выдает следующие ошибки:
main.cpp: In function 'int main()':
main.cpp:11:11: error: invalid initialization of non-const reference of type 'char&' from an rvalue of type 'char'
f2(f1()); // error C2664. This is as expected.
^
main.cpp:2:6: error: in passing argument 1 of 'void f2(char&)'
void f2(char&);
^
main.cpp:12:12: error: invalid initialization of non-const reference of type 'A&' from an rvalue of type 'A'
f4(f3()); // OK! Why???
^
main.cpp:7:6: error: in passing argument 1 of 'void f4(A&)'
void f4(A&);