Returning std::move of a local variable [duplicate]

♀尐吖头ヾ 提交于 2019-12-24 17:04:56

问题


Let there be a class A with a move constructor. Consider this:

A get()
{
    A a;
    return std::move( a );
}

// later in the code
A aa = get();

Here the explicit call to std:move forces the move constructor of A to be called thus it might inhibit the return value optimization in while calling get(). Thus it is said the a better implementation of get() would be this:

A get()
{
    A a;
    return a;
}

But the return value optimization is not a part of C++11 standard, so WHAT IF the compiler, by some reason, decides not to perform return value optimization while calling get(). In this case a copy constructor of A will be called while returning in get() right?

So isn't the first implementation of get() more pereferible??


回答1:


A compiler should use a move constructor, but I didn't see an obligation in the standard : It's always said "Copy/move constructor" in the section concerning temporary objects

standard ISO/IEC 14882:2011 C++ :

"

12.1/9

A copy constructor (12.8) is used to copy objects of class type. A move constructor (12.8) is used to move the contents of objects of class type.

12.8/32

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. [ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. — end note ]

"

lvalue = T &
rvalue = T &&

So, It says that first, the compiler will look if it find a move constructor, then, it will look for a move constructor.

Thus, if your compiler is conform to the standard, it will call the move constructor.

I append just that which is interesting:

"
12.8/31 When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects.
"

...So even if there is side effects in these constructors/destructors, they can be skipped



来源:https://stackoverflow.com/questions/18227977/returning-stdmove-of-a-local-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!