为什么在这种情况下调用右值引用构造函数?
Why is r-value reference constructor called in this case?
#include<iostream>
using namespace std;
struct B{};
struct A
{
A(const B &)
{
cout<<"A(const B &)"<<endl;
}
A(B &&)
{
cout<<"A(B &&)"<<endl;
}
};
A get()
{
B b;
return b;
}
int main()
{
get();
}
我用 VC++14.2 和 GCC 5.4.0 测试了代码,它们都输出:
A(B &&)
为什么输出不是
A(const B &)
?
这段代码和copy elision
有关系吗? (但是A和B是不同的类型,所以copy elision
这里应该不行)
return-as-rvalue 规则已更改,以响应 C++14 发布前的审查。更改是在过程的后期添加的,并由 CWG Issue 1579 捕获,用措辞修改 12.8/32:
or when the expression in a return
statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body
这意味着 returning 任何局部变量现在首先将由该变量指定的对象视为右值(如果重载解析失败,则重试)。
由于 CWG 问题被认为是语言中的一个缺陷,编译器甚至可以在 "C++11 mode" 中实施这一新规则。缺陷点是"it was always meant to work that way",所以严格来说这不是C++11和C++14之间的变化,而是C++11的含义在2014年被修改了
复制省略与 A 相关,不是在 get() 堆栈框架中构造的。
发生的事情是返回的 b
(这是临时的,因为 "going to die because of return":这是从 C++14 开始的),用于在主堆栈框架中构造复制省略的 A
。
并且由于临时对象绑定了 r 值引用,这就是您观察到的情况。
#include<iostream>
using namespace std;
struct B{};
struct A
{
A(const B &)
{
cout<<"A(const B &)"<<endl;
}
A(B &&)
{
cout<<"A(B &&)"<<endl;
}
};
A get()
{
B b;
return b;
}
int main()
{
get();
}
我用 VC++14.2 和 GCC 5.4.0 测试了代码,它们都输出:
A(B &&)
为什么输出不是
A(const B &)
?
这段代码和copy elision
有关系吗? (但是A和B是不同的类型,所以copy elision
这里应该不行)
return-as-rvalue 规则已更改,以响应 C++14 发布前的审查。更改是在过程的后期添加的,并由 CWG Issue 1579 捕获,用措辞修改 12.8/32:
or when the expression in a
return
statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body
这意味着 returning 任何局部变量现在首先将由该变量指定的对象视为右值(如果重载解析失败,则重试)。
由于 CWG 问题被认为是语言中的一个缺陷,编译器甚至可以在 "C++11 mode" 中实施这一新规则。缺陷点是"it was always meant to work that way",所以严格来说这不是C++11和C++14之间的变化,而是C++11的含义在2014年被修改了
复制省略与 A 相关,不是在 get() 堆栈框架中构造的。
发生的事情是返回的 b
(这是临时的,因为 "going to die because of return":这是从 C++14 开始的),用于在主堆栈框架中构造复制省略的 A
。
并且由于临时对象绑定了 r 值引用,这就是您观察到的情况。