截至cplusplus.com指出,std::forward
有兩個特徵:爲什麼有兩個std :: forward簽名?
template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept;
template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;
的典型用途std::forward
是維護rvalueness而通過其他函數的參數。讓我們來說明這一個例子:
void overloaded(int &) { std::cout << "lvalue"; }
void overloaded(int &&) { std::cout << "rvalue"; }
template <typename T>
void fwd(T && t)
{
overloaded(std::forward<T>(t));
}
當我們調用fwd(0)
,T
演繹到int
(t
的類型爲int &&
)。然後我們撥打std::forward<int>(t)
。該調用的結果是int &&
類型的表達式,因此選擇第二個版本的overloaded
函數,程序將「右值」輸出到標準輸出。
當我們調用fwd(i)
(其中,i是一些int變量),T
推斷到int&
(t
具有類型int &
)。然後我們撥打std::forward<int&>(t)
。該調用的結果(在應用參考摺疊規則之後)是int &
類型的表達式,因此選擇overloaded
函數的第一個版本,並且程序將「左值」打印到標準輸出。
在這兩種情況下,我們使用std::forward
(取typename remove_reference<T>::type& arg
)的第一個過載。這是因爲即使t
的類型爲int &&
,它也會綁定到左值引用(因爲類型「右值引用某個元素」的名稱變量本身是左值,左值不能綁定右值引用)。
問題1:
那是什麼的std::forward
秒過載?你能想到一個實際的例子,它使用了右值參考arg
的過載。
問題2:
Both signatures return the same as:
static_cast<decltype(arg)&&>(arg)
我有這個問題,是,我敢肯定,這是錯誤的。當我們嘗試從std::forward
的第一個重載中返回時,我們得到一個編譯錯誤。
當fwd
被調用int
右值時,它會調用std::forward
的第一個重載與T = int
。然後,decltype(arg)
將變爲int&
,因此static_cast<decltype(arg)&&>(arg)
將摺疊爲static_cast<int&>(arg)
。但是,返回類型爲int &&
,我們得到的編譯錯誤:
cannot bind ‘std::remove_reference<int>::type {aka int}’ lvalue to ‘int&&’
的std::forward
兩個重載版本應該返回static_cast<T&&>(arg)
。我對嗎?
你認爲cplusplus.com的報價是錯誤的嗎?
有關第一個問題的答案,請參見http://stackoverflow.com/questions/38344332/why-does-stdforward-have-two-overloads。 – TartanLlama
@TartanLlama那個有一堆'const'和'const_cast'灑在整個tho。 – Yakk
'cplusplus.com'不是'cppreference'。 'cppreference.com'是'cppreference'。知道區別。 – Nawaz