This is a follow-on question to C++0x rvalue references and temporaries

In the previous question, I asked how this code should work:

void f(const std::string &); //less efficient
void f(std::string &&); //more efficient

void g(const char * arg)
{
    f(arg);
}

It seems that the move overload should probably be called because of the implicit temporary, and this happens in GCC but not MSVC (or the EDG front-end used in MSVC's Intellisense).

What about this code?

void f(std::string &&); //NB: No const string & overload supplied

void g1(const char * arg)
{
     f(arg);
}
void g2(const std::string & arg)
{
    f(arg);
}

It seems that, based on the answers to my previous question that function g1 is legal (and is accepted by GCC 4.3-4.5, but not by MSVC). However, GCC and MSVC both reject g2 because of clause 13.3.3.1.4/3, which prohibits lvalues from binding to rvalue ref arguments. I understand the rationale behind this - it is explained in N2831 "Fixing a safety problem with rvalue references". I also think that GCC is probably implementing this clause as intended by the authors of that paper, because the original patch to GCC was written by one of the authors (Doug Gregor).

However, I don't this is quite intuitive. To me, (a) a const string & is conceptually closer to a string && than a const char *, and (b) the compiler could create a temporary string in g2, as if it were written like this:

void g2(const std::string & arg)
{
    f(std::string(arg));
}

Indeed, sometimes the copy constructor is considered to be an implicit conversion operator. Syntactically, this is suggested by the form of a copy constructor, and the standar

Edit
Report