Perfect Forwarding
介紹
Perfect Forwarding
Perfect Forwarding 指的是函式可以原封不動 (保持原 lvalue/rvalue 性質)地把資料傳給真正要建立的地方, 藉此可以省去中間傳遞時不必要的複製。
std::forward
std::forward 是一個 conditional cast, 如果傳入的參數原本是 rvalue 的話, 才會進行轉換, 把它轉成 rvalue。
相對的 std::move 是無論如何都會把傳入的參數轉成 rvalue。
template<class T>
void wrapper(T&& arg)   // universal reference
{
    // arg is always lvalue
    foo(std::forward<T>(arg)); // Forward as lvalue or as rvalue, depending on T
}
emplace
在 C++11 之後 STL 內的資料結構都多了 emplace 相關的函式可以呼叫, 以 vector 為例:
- push_back(mystring):copy
- push_back(std::move(mystring)):move
- emplace_back(mystring):copy,等同於- push_back(mystring)
- emplace_back(std::move(mystring)):move,等同於- push_back(std::move(mystring))
- emplace_back("mydata"):in-place construction
使用 emplace 版本的結果可能會等同於原本的版本, 但在直接傳入內部資料時, emplace 版本就會比較有效率。
搭配 Variadic Template
template<typename... Args>
void stepper::rturn(Args&&... args) const
{
    turn(std::forward<Args>(args)..., true);
}
結論
- 對 rvalue reference 使用 std::move
- Widget&&是 rvalue reference
- vector<T>&&是 rvalue reference
 
 
- 對 universal reference 使用 std::forward
- T&&是 universal reference
- auto&&是 universal reference
 
 
- 如果是會被 RVO/NRVO 優化掉的 local 物件,不要套用 std::move 或 std::forward 
rvalue reference:
class Widget {
public:
    Widget(Widget&& rhs)    // rhs is rvalue reference
    : name(std::move(rhs.name)),
      p(std::move(rhs.p))
    { ... }
    ...
private:
    std::string name;
    std::shared_ptr<SomeDataStructure> p;
};
universal reference:
class Widget {
public:
    template<typename T>
    void setName(T&& newName)   // universal reference
    { name = std::forward<T>(newName); }
    ...
};