Временная привязка к ссылке lvalue

У меня есть следующий код

string three()
{
    return "three";
}

void mutate(string& ref)
{
}

int main()
{
    mutate(three()); 
    return 0;
}

Как видите, я передаю three () методу mutate. Этот код хорошо компилируется. Насколько я понимаю, временные объекты не могут быть назначены неконстантным ссылкам. Если да, то как компилируется эта программа?

Есть предположения?

Изменить:

Компиляторы попробовали: VS 2008 и VS2010 Beta


person Navaneeth K N    schedule 28.08.2009    source источник
comment
Попробуйте GCC, он ближе к стандарту C ++.   -  person Learner    schedule 28.08.2009
comment
К сожалению, у меня нет с собой GCC.   -  person Navaneeth K N    schedule 28.08.2009
comment
@Appu: После того, как я исправил в вашем коде отсутствующие включения и префиксы std, Comeau (comeaucomputing.com/tryitout) говорит: initial value of reference to non-const must be an lvalue. Причина, по которой VC принимает это, состоит в том, что VC не работает. (Они называют это функцией, но на самом деле это ошибка.)   -  person sbi    schedule 28.08.2009


Ответы (5)


Он использовался для компиляции в компиляторе VC6, поэтому я предполагаю, что для обеспечения обратной совместимости VS2008 поддерживает это нестандартное расширение. Попробуйте с флагом / Za (отключить расширение языка) , тогда вы должны получить сообщение об ошибке.

person Naveen    schedule 28.08.2009
comment
Указание параметра /Za может привести к проблемам с включением windows.h или других заголовков, специфичных для Windows. - person Kirill V. Lyadvinsky; 28.08.2009
comment
Использование уровня предупреждения как четыре - лучший вариант, это то, что я использовал - person yesraaj; 28.08.2009

Это злое расширение VC ++. Если вы компилируете с / W4, компилятор предупредит вас. Думаю, вы читаете Ссылки на Rvalue: возможности C ++ 0x в VC10, часть 2. В этой статье также упоминалась эта проблема.

person yoco    schedule 28.08.2009

Это расширение Microsoft, имитирующее поведение многих других компиляторов Microsoft. Если вы включите предупреждения W4, вы увидите предупреждение.

person QbProg    schedule 28.08.2009

Он не компилируется, по крайней мере, с g ++ 4:

foo.cpp: In function ‘int main()’:
foo.cpp:16: error: invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type ‘std::string’
foo.cpp:10: error: in passing argument 1 of ‘void mutate(std::string&)’

(Номера строк отличаются на 3 или 4, потому что мне пришлось добавить строки #include и 'using'.)

Итак, ваш компилятор не такой строгий, каким должен быть.

person Warren Young    schedule 28.08.2009
comment
Отредактированный пост и добавленные компиляторы, которые я использую. - person Navaneeth K N; 28.08.2009

Думаю, это зависит от компилятора. g ++ 4.1.2 дает мне это.

In function 'int main()':
Line 15: error: invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'std::string'
compilation terminated due to -Wfatal-errors.

Возможно, из-за того, что вы ничего не делаете, вызов оптимизируется.

person Adis H    schedule 28.08.2009
comment
Я пытался что-то сделать с параметром ref внутри метода mutate (), но он все еще компилируется - person Navaneeth K N; 28.08.2009
comment
Я только что пробовал его на VC ++, и он компилируется и работает, если вы не отключите расширения в свойствах проекта. Когда вы получите это: 1 ›main.cpp 1› d: \ all \ projects \ laptop \ 2 \ asd \ asd \ main.cpp (16): ошибка C2664: 'mutate': невозможно преобразовать параметр 1 из 'std :: string 'to' std :: string & '1 ›Неконстантная ссылка может быть привязана только к lvalue - person Adis H; 28.08.2009