函数返回值和右值引用绑定 我试图理解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

函数返回值和右值引用绑定 我试图理解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,c++,c++11,move-semantics,C++,C++11,Move Semantics,这里我不明白的是t0是如何构造的。我希望使用Test(Test&)作为MakeTest()的返回值是未命名的临时值来构造 你能解释一下为什么它不调用我定义的3个构造函数中的任何一个吗 @Angew的评论很可能是对的,复制/移动省略必须收费 另一点可能是,即使Test(t)是临时的,它仍然是一个值,因此复制构造函数更接近匹配 无论如何,如果希望确实使用move构造函数,可以使用std::move() 我多次使用它,因为一旦我们使用move构造函数,构造函数中很容易出现一些技巧,我们确实希望被调用。

这里我不明白的是
t0
是如何构造的。我希望使用
Test(Test&)
作为
MakeTest()
的返回值是未命名的临时值来构造


你能解释一下为什么它不调用我定义的3个构造函数中的任何一个吗

@Angew的评论很可能是对的,复制/移动省略必须收费

另一点可能是,即使Test(t)是临时的,它仍然是一个值,因此复制构造函数更接近匹配

无论如何,如果希望确实使用move构造函数,可以使用std::move()


我多次使用它,因为一旦我们使用move构造函数,构造函数中很容易出现一些技巧,我们确实希望被调用。

复制/移动可能会被省略。搜索“返回值优化”或“复制省略”。@Angew I禁用了所有优化。我不希望在这里使用RVO和复制省略…@Felics您提供了一个命令行参数,该参数表示“不要进一步优化”-这不是禁用RVO之类的简单功能。@Felics复制省略实际上是语言的一部分-通常您必须明确告诉编译器不要这样做(如果他们允许的话),只要说“不要优化”还不够。尝试
-fno elide构造函数
。添加
std::move
可以防止省略,只会使程序变慢,而不会变快。这是个坏主意。
------------------------------
Test()
Test(const Test&)
~Test()
------------------------------
Test()
Test(const Test&)
~Test()
Test(Test&&)
~Test()
------------------------------
~Test()
~Test()
Test MakeTest()
{
    Test t;
    return std::move(Test(t));
}