3

I think I learn from TC++PL that "A non-const reference should be initialized by a left-value".

And the following is my question

int f1(int &x)
{
    return 1;
}

int f2()
{
    return 1;
}

int f3(string &s)
{
    return 1;
}

string f4()
{
    return "1";
}

int main()
{
    cout<<f1(f2())<<endl; // Error.
    cout<<f3(f4())<<endl; // OK.
}

So I cann't understand that why f3(f4()) is correct while the return value of f4() is obvious not a left-value.

hwlts
  • 33
  • 3

4 Answers4

4

I think, you use Microsoft Visual C++ Compiler, that with default options compile this code. It's since there is non-standard extension in it, that allows bind rvalues to lvalue-references. For more information, about how can this work in MSVC you can read rvalue to lvalue conversion Visual Studio

Community
  • 1
  • 1
ForEveR
  • 55,233
  • 2
  • 119
  • 133
2

Both the statements will not work. reason is that f(2) is returning a constant value and f(1) expects a non constant and hence the error message.

int f3(const string &s)
{
   return 1;
}

int f1(const int &x)
{
   return 1;
}

This will do away with the error.

Ankur Jain
  • 164
  • 3
  • 12
0

Conceptually this code should not work. Why?

Answer: Each of the functions f1 and f3 use a parameter as a call by address. So it's got to be able to refer to the address of the parameter passed to it. Thus any change to the values of the parameter in functions f1 and f3 should affect the actual variables that were passed to it.

But the returning value of functions f4 and f2 are constants and cannot be altered. Thus the errors.

Now, if all you need to do is pass the values of functions f2 and f4 into functions f1 and f3, simply pass them by value. And to do this, remove the & signs in the parameters.

itsols
  • 5,406
  • 7
  • 51
  • 95
  • Why does f1 take parameter as "call by address"? It simply takes reference as a parameter – Subhajit Apr 24 '13 at 11:25
  • @Subhajit If you noticed, this **(int &x)**, it's a call by reference/address. But if you do this **(int x)**, it's a call by value. Now you can pass EITHER another variable or a constant value. Hope that's clear – itsols Apr 24 '13 at 11:27
-1
int _tmain(int argc, _TCHAR* argv[])
{
    cout<<f1(f2())<<endl; 
    int &a(1); //This is what gonna happen when your f2() returns 1 and 1 is passed in    f1(int&). That is invalid.
        cout<<f3(f4())<<endl; 
    // string& str(string("1"));//when "1" is returned from f4() it will be implicitly casted to string("1") and pass in f3 as f3(string("1")). There it comes valid reference.


    return 0;
}
kalpesh
  • 21
  • 6
  • "_This is what gonna happen when your f2() returns 1_" - What? `f2()` returns _prvalue_, how can it be casted to reference? – awesoon Apr 24 '13 at 11:35
  • 1
    Yes it can not be casted to reference that is why it shows the error. – kalpesh Apr 24 '13 at 11:40
  • Sorry, it's my mistake. But you told: "_There it comes valid reference_" for the second case. Does it mean, that `string& str(string("1"));` is valid, or I missed something (again >_<)? – awesoon Apr 24 '13 at 11:48