C ++函数和右值混淆

时间:2017-08-31 18:44:20

标签: c++ rvalue

参考以下代码:

// 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

为什么代码调用move constructor而不是函数S goo()?如果你注释掉第一行,那么它就不会。

为什么S goo()的返回类型会有所不同,具体取决于main中的第一行?我不认为这应该编译,但在这里编译 http://cpp.sh/22zeq

(不在wandbox上编译:https://wandbox.org/permlink/3YxBdcWs91FRiODG

正在阅读此处的示例:http://thbecker.net/articles/rvalue_references/section_05.html 当我偶然发现这个

3 个答案:

答案 0 :(得分:2)

由于每个人似乎都在理解main中的S&& goo();(它声明了一个函数),但人们似乎不明白最后如何调用S goo()

原因是返回值不是函数签名的一部分。因此,当您致电goo()时,您最终会调用唯一可用的版本 - 一个返回S。我相信,这是未定义行为的一个例子。

答案 1 :(得分:1)

这是因为S&& goo();新功能的声明。 但是当你编译时,它只存在一个名为S goo();的函数,这就是它被调用的原因。

这是链接器的工作。它没有找到任何具有此类名称的函数,并将其链接到S goo();

答案 2 :(得分:1)

返回类型不同,因为S&& goo();函数声明。所以,它构造任何东西。

它告诉编译器goo是一个返回S&&并且不带参数的函数。这会覆盖任何其他先前的声明,因此,对于main函数,goo会返回S&&。当您注释掉该行时,只有函数定义定义了返回类型。

这也适用于Ideone。也就是说,在main内,goo的返回类型已更改为S&&