Não é possível transmitir objeto temporário como referência

Este é um exemplo muito mínimo:

class Foo
{
public:
    Foo(int x) {};
};

void ProcessFoo(Foo& foo)
{
}

int main()
{
    ProcessFoo(Foo(42));
    return 0;
}

O acima compila bem no Visual Studio, mas gera um erro no Linux e Mac.

A compilação acima gera isso:

$ g++ -std=c++11 -c newfile.cpp

newfile.cpp: In function ‘int main()’:
newfile.cpp:23:23: error: invalid initialization of non-const reference of type ‘Foo&’ from an rvalue of type ‘Foo’
     ProcessFoo(Foo(42));
                       ^
newfile.cpp:14:6: note: in passing argument 1 of ‘void ProcessFoo(Foo&)’
 void ProcessFoo(Foo& foo)

Eu encontrei três soluções alternativas:

Evite o uso de uma variável temp inline para a chamada do ProcessFoo.

Como isso:

Foo foo42(42);
ProcessFoo(foo42);

ProcessFoo usa uma referência const:void ProcessFoo(const Foo& foo)

O ProcessFoo apenas permite que o Foo seja transmitido por valor.void ProcessFoo(Foo foo)

Por que o compilador está proibindo meu código original? (Contra o que ele está se escondendo)? O que há em cada uma das três soluções alternativas acima que satisfaz o compilador? O que o MSVC permitiria, mas não o g ++?

questionAnswers(4)

yourAnswerToTheQuestion