2017-08-03 53 views
0
std::string my_func(){ 
    return std::string("..."); 
} 

std::string可以替换为std::vector或其他任何东西。一般来说,我如何知道rv已被移动并且未被复制?我如何知道rv已被移动且未被复制?

+2

读取生成的汇编语言代码。 –

+0

它可能根本不会被移动或复制。 – juanchopanza

+0

它被移动或复制。答案是重要的,因为我坚持写的东西,如果它被移动,我宁愿写'void my_func(std :: string & str);'而不是如果它不 – user3600124

回答

2

移动构造函数接受右值引用。在处理prvalues时,右值引用优于对const的左值引用。所以,只要你的类型有一个有效的移动构造函数,编译器就会选择移动构造函数,并且只有在没有移动构造函数时才会回退到复制构造函数。

这就是说在这种情况下很可能没有任何东西会被复制或移动,并且RVO将会在其中直接在呼叫站点构建对象。要知道它是否唯一的方法是检查组件。

从C++ 17开始,使用guaranteed copy elision确保您确实无法复制或移动。

5

cppreference

在C++ 11,表达式...... 没有身份,可以从被称为prvalue( “纯右值”)表达式中移动。

的临时对象,像您正在返回的一个(std::string("..."))没有身份,并且可以从,因为编译器可以检测到它的状态也不会其寿命结束之前被使用来移动。因此,编译器宁愿移动该对象来复制它。

然而,临时对象很可能无法移动或复制,因为在所有的返回值优化(RVO)copy elision优化该构造对象,它本来被移动到存储形式。因此,如果您要编写std::string str = my_func();,代码可能会进行优化,以便在原地构建str"...",而不是在my_func()内构建一个字符串,然后将其移出。 RVO适用于任何可复制和/或可移动的物体。

相关问题