Rvalue to lvalue conversion Visual Studio

В Visual Studio 2012RC есть несколько нестандартных расширений. Например, этот код компилируется:

#include <string>

using namespace std;

void value(string& value)
{
    value = "some";
}

int main()
{
    value(string("nice"));
}

и получите предупреждение о том, что это нестандартное расширение. Итак, я хочу понять, как это реально и как преобразуются коды (rvalue-reference или const ссылка с const_cast)?

Ответ 1

Временным объектом типа класса по-прежнему является объект. Он живет где-то в памяти, а это означает, что в компиляторе нет ничего необычного, чтобы прикрепить ссылку на него. На физическом уровне, независимо от того, является ли это константной ссылкой или неконстантной ссылкой, нет никакой разницы. Другими словами, в таких случаях ограничение языка является чисто концептуальным, искусственным. Компилятор просто игнорирует это ограничение. Здесь нет необходимости "трансформировать" что-либо. Ссылка просто привязана непосредственно к объекту, где бы он ни находился.

В принципе, для класса, который предоставляет внешнему слову доступ к значению его указателя this (или с lvalue-доступом к *this), поведение может быть немедленно и легко смоделировано

struct S {
  S& get_lvalue() { return *this; }
};

void foo(S& s);
...

foo(S().get_lvalue());

Вышеприведенный код совершенно легален и работает вокруг вышеупомянутого ограничения. Вы можете думать, что поведение MSVС++ эквивалентно этому.

Ответ 2

В принципе, VS будет выделять пространство где-то и просто дать ссылку на него, как если бы это была ссылка-to- const без константы (или в С++ 11 ссылка rvalue).

Вы можете отключить это поведение с помощью компилятора /Za (отключить расширение языка) в

Свойства → C/С++ → Язык

Если я правильно помню.

Ответ 3

В стандартном С++ вы не можете привязать временную (rvalue/ string("nice")) к неконстантной ссылке (lvalue), но это позволяет компилятор microsoft. Предупреждение сообщает вам, что код компилируется из-за расширения и не будет компилироваться с любым другим компилятором.