函数返回值和右值引用绑定
Function return values and rvalue references binding
我正在尝试理解C中的移动语义和完美转发++为了做到这一点,我制作了下一个简单的程序:
#include <iostream>
struct Test
{
Test(){ std::cout << "Test()" << std::endl; }
Test(Test&&){ std::cout << "Test(Test&&)" << std::endl; }
Test(const Test&){ std::cout << "Test(const Test&)" << std::endl; }
~Test(){ std::cout << "~Test()" << std::endl; }
};
Test MakeTest()
{
Test t;//output Test()
return Test(t);//output Test(const Test&)
}//output ~Test
int main()
{
std::cout << "------------------------------" << std::endl;
Test t0(MakeTest()); //How is t0 constructed!??
std::cout << "------------------------------" << std::endl;
Test t1(std::forward<Test>(MakeTest())); //output Test(Test&&) n ~Test
std::cout << "------------------------------" << std::endl;
return 0;
}//output ~Test n ~Test
该程序有以下输出(VS2013,GCC 4.8-调试mdoe,优化关闭):
------------------------------
Test()
Test(const Test&)
~Test()
------------------------------
Test()
Test(const Test&)
~Test()
Test(Test&&)
~Test()
------------------------------
~Test()
~Test()
这里我不明白的是t0
是如何构造的。我期望使用Test(Test&&)
来构造,因为MakeTest()
的返回值是未命名的临时值。
你能解释一下为什么它不调用我定义的3个构造函数中的任何一个吗?
@Angew的评论很可能是对的,复制/移动省略必须收费。
另一点可能是,即使Test(t)是临时的,它仍然是一个值,因此复制构造函数更匹配。
无论如何,如果您确实希望使用move构造函数,您可以使用std::move()。
Test MakeTest()
{
Test t;
return std::move(Test(t));
}
我用了好几次,因为一旦我们使用了move构造函数,构造函数中很容易出现一些技巧,我们确实希望被调用。
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 将常量指针引用绑定到非常量指针
- 运行时错误:引用绑定到类型为"int"的空指针
- 模板允许左值与右值引用绑定
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 将引用绑定到指针的语法是什么?(各种)
- 为什么我不能将常量左值引用绑定到返回 T&&&的函数?
- 为什么 VS 无法将右值引用绑定到指针?
- 出于什么原因,有必要将常量左值引用绑定到右值?
- 为什么此右值引用绑定到左值?
- 使用“void*”将右值引用绑定到左值
- 排序时引用绑定到 'value_type' 类型的 null 指针
- 无法将类型为"类名 &"的非常量左值引用绑定到类型为"类名"的右值
- 引用绑定和复制构造函数/移动构造函数
- 将引用绑定到类型的值会删除限定符 MULTISET
- 无法将类型"int&"的非常量左值引用绑定到类型为"int"的右值
- 多态变体,并将一种类型的引用绑定到另一种类型的引用
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)