關於std::forward
的建議通常限於完美轉發函數模板參數的規範用例; some commentators竟然說這是只有有效使用std::forward
。但考慮這樣的代碼:std ::轉發沒有完美轉發?
// Temporarily holds a value of type T, which may be a reference or ordinary
// copyable/movable value.
template <typename T>
class ValueHolder {
public:
ValueHolder(T value)
: value_(std::forward<T>(value)) {
}
T Release() {
T result = std::forward<T>(value_);
delete this;
return result;
}
private:
~ValueHolder() {}
T value_;
};
在這種情況下,完美轉發的問題不會出現:因爲這是一個類模板而不是函數模板,客戶端代碼必須明確指定T
,並且可以選擇是否和如何重新鑑定它。同樣,std::forward
的論點不是「通用參考」。
儘管如此,std::forward
似乎這裏是一個不錯的選擇,我們不能就這麼走了出來,因爲當T
是唯纔是舉型這是行不通的,我們不能用std::move
因爲不會當T
是一個左值引用類型時工作。當然,我們可以部分專用ValueHolder
來使用參考的直接初始化和std::move
的值,但是當std::forward
完成這項工作時,這看起來過於複雜。對於std::forward
的含義,這似乎也是一個合理的概念匹配:我們試圖一般性地轉發可能或可能不是參考的東西,只是將它轉發給函數的調用者,而不是函數稱自己。
這是一個健全的使用std::forward
?有什麼理由避免它?如果是這樣,那麼最好的選擇是什麼?
'std :: forward',在這種情況下,沒有任何意義。 'T'是類模板的參數,而不是構造函數/函數。當你讓編譯器推導出類型時,'std :: forward'是有意義的,在函數模板的情況下這是可能的。 – Nawaz
如果參數是T && – polkadotcadaver
,這隻有一點意義。如果您願意,這是一個完美轉發的擴展案例。它變得更清晰,如果你有一個'template ValueHolder make_holder(T && v){return {std :: forward (v)}; }工廠功能。用戶提供的'T'還是通過工廠函數是無關緊要的。 (儘管我建議不要刪除這個部分。) –
Xeo