从 returns Boost 可选的函数返回右值引用
Returning rvalue reference from a function that returns Boost optional
从 Boost 1.56 开始,Boost 可选支持移动语义。那么,下面的构造有意义吗?
boost::optional<SomeType> getValue()
{
if (value_available) { // value_available is a boolean
return std::move(value); // value is of type SomeType
} else {
return boost::none;
}
}
只有当您只需要调用 getValue()
一次,或者所有权转移语义适用时,它才有意义,因为它会在第一次调用后销毁 value
。
是的,这很有意义。这意味着你从 value
移动,以防万一。
然而,当 语义上 class 已经包含一个可选值(value_available
是那个指标)。
所以,我建议将 value
存储为 optional<T>
并且 just return that
return value; // already optional!
在这种情况下,您可以免费获得正确的移动语义和 RVO。当然如果value
不是local或者temporary,就需要说
return std::move(value);
(Sidenote: I don't agree with the other answer that this is only useful if getValue()
is called only once. If your type has a well-defined "default" state to return to after move, then it could become a sort of "1-element queue".)
In such a case it might be nice to explicitly uninitialize the source value before returning. I think it is tricky to implement this exchange in an exception safe way though.
Consider renaming the function to e.g. popValue()
, extractValue()
or consume()
to explicitly mention the fact that using this function moves from internal object state. Of course, some warning is already implicitly present in the fact that the member function is not const
but good naming is important too
从 Boost 1.56 开始,Boost 可选支持移动语义。那么,下面的构造有意义吗?
boost::optional<SomeType> getValue()
{
if (value_available) { // value_available is a boolean
return std::move(value); // value is of type SomeType
} else {
return boost::none;
}
}
只有当您只需要调用 getValue()
一次,或者所有权转移语义适用时,它才有意义,因为它会在第一次调用后销毁 value
。
是的,这很有意义。这意味着你从 value
移动,以防万一。
然而,当 语义上 class 已经包含一个可选值(value_available
是那个指标)。
所以,我建议将 value
存储为 optional<T>
并且 just return that
return value; // already optional!
在这种情况下,您可以免费获得正确的移动语义和 RVO。当然如果value
不是local或者temporary,就需要说
return std::move(value);
(Sidenote: I don't agree with the other answer that this is only useful if
getValue()
is called only once. If your type has a well-defined "default" state to return to after move, then it could become a sort of "1-element queue".)In such a case it might be nice to explicitly uninitialize the source value before returning. I think it is tricky to implement this exchange in an exception safe way though.
Consider renaming the function to e.g.
popValue()
,extractValue()
orconsume()
to explicitly mention the fact that using this function moves from internal object state. Of course, some warning is already implicitly present in the fact that the member function is notconst
but good naming is important too