11.29 C++核心準則F.45 不要返回右值引用

C++核心準則F.45 不要返回右值引用

F.45: Don't return a T&&

F.45:不要返回右值引用

Reason(原因)

It's asking to return a reference to a destroyed temporary object. A && is a magnet for temporary objects.

返回右值引用是在要求返回一個已經銷燬的臨時對象的引用。&&對於臨時對象來說具有吸引力。

譯者注:後面這句真沒理解。

Example(示例)

A returned rvalue reference goes out of scope at the end of the full expression to which it is returned:

返回的右值引用在所有表達式的最後一個返回時退出了有效範圍。

auto&& x = max(0, 1); // OK, so far
foo(x); // Undefined behavior

This kind of use is a frequent source of bugs, often incorrectly reported as a compiler bug. An implementer of a function should avoid setting such traps for users.

這種用法是bug的常見原因。經常被錯誤地報告為編譯器錯誤。函數的實現者應該避免給使用者佈置這樣的陷阱。

The lifetime safety profile will (when completely implemented) catch such problems.

生命週期安全規則群組會(在完全實現的情況下)捕捉這樣的問題。

Example(示例)

Returning an rvalue reference is fine when the reference to the temporary is being passed "downward" to a callee; then, the temporary is guaranteed to outlive the function call (see F.18 and F.19). However, it's not fine when passing such a reference "upward" to a larger caller scope. For passthrough functions that pass in parameters (by ordinary reference or by perfect forwarding) and want to return values, use simple auto return type deduction (not auto&&).

當引用的對象是向下(向內)傳遞給調用者時返回右值引用時會工作得很好。這種情況下可以保證臨時變量的生命週期會長於函數調用(參見F.18和F.19)。然而,當將這個引用向上(向外)傳遞給更大的調用者空間時是有問題的。對於傳遞輸入參數(通過原始引用或者完美的fowrard處理)而且需要返回值的透過型函數,使用簡單的auto類型返回類型推斷(不是auto&&)。

Assume that F returns by value:

假設F是通過值返回的:

template<class>
auto&& wrapper(F f)
{
log_call(typeid(f)); // or whatever instrumentation
return f(); // BAD: returns a reference to a temporary
}/<class>

Better(較好):

template<class>
auto wrapper(F f)
{
log_call(typeid(f)); // or whatever instrumentation

return f(); // OK
}/<class>

Exception(例外)

std::move and std::forward do return &&, but they are just casts -- used by convention only in expression contexts where a reference to a temporary object is passed along within the same expression before the temporary is destroyed. We don't know of any other good examples of returning &&.

std::move和std::forward也會返回&&,但是按照慣例它們只是用於臨時變量被銷燬之前,它的引用在同一表達式內傳遞的情況。我們不知道其他任何返回&&的好例子。

Enforcement(實施建議)

Flag any use of && as a return type, except in std::move and std::forward.

標記使用&&做返回值類型的用法,除了std::move和std::forward。


覺得本文有幫助?請分享給更多人。

面向對象設計,面向對象編程,面向對象思考!


分享到:


相關文章: