C++ function and rvalue confusion

114 Views Asked by At

with reference to the following code:

// Example program
#include <iostream>
#include <string>
using namespace std;

struct S
{
    S()
    {
        cout << "ctor\n";
    }
    S(S&& rhs)
    {
        cout << "called move\n";
    }
};

S goo()
{
    S a;
    return a;
}

int main()
{

 S&& goo();
 cout << "before construction\n";
 S a = goo();

}
//http://thbecker.net/articles/rvalue_references/section_05.html

why is the code calling the move constructor and not the function S goo()? If you comment out the first line then it does not.

why is the return type of S goo() different depending on the first line in main? I dont think this should even compile but compiles here http://cpp.sh/22zeq

(does not compile on wandbox: https://wandbox.org/permlink/3YxBdcWs91FRiODG)

was reading an example on here: http://thbecker.net/articles/rvalue_references/section_05.html when i stumbled upon this

3

There are 3 best solutions below

6
On

It is because S&& goo(); is declaration of new function. But when you compile it exists only one function with such name S goo(); that is why it was called.

It is a work of linker. It has not found any another function with such name and linked it to S goo();

0
On

The return type is different because S&& goo(); is a function declaration. So, it does not construct anything.

It tells the compiler that goo is a function that returns S&& and takes no arguments. This overwrites any other previous declarations, so, for the main function, goo returns a S&&. When you comment that line out, only the function definition defines the return type.

This also works on Ideone. That is, inside main the return type of goo has changed to S&&.

3
On

Since everybody seems to be in understanding of what S&& goo(); in main does (it declares a function) but people seem to not understand how S goo() get's called in the end.

The reason for this is the fact that return value is not part of function signature. So when you call goo(), you end up calling the only version of it which is available - one returning S. I believe, this is an example of undefined behavior.