2014-01-08 136 views
2

我剛讀到Visual Studio的STL實現的algorithm.h頭回來,我發現下面的代碼時使用招:爲什麼的std ::這個功能

template<class _InIt, 
    class _Fn1> inline 
    _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func) 
    { // perform function for each element 
    _DEBUG_RANGE(_First, _Last); 
    _DEBUG_POINTER(_Func); 
    _For_each(_Unchecked(_First), _Unchecked(_Last), _Func); 

    return (_STD move(_Func)); 
    } 

...代碼的重要組成部分是:

template<class _InIt, class _Fn1> 
inline _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func) 
{ // perform function for each element 
    _For_each(_Unchecked(_First), _Unchecked(_Last), _Func); 
    return (std::move(_Func)); 
} 

...這裏是_For_each功能的簽名

template<class _InIt, 
    class _Fn1> inline 
    void _For_each(_InIt _First, _InIt _Last, _Fn1& _Func) 

而我的問題是爲什麼在這種情況下返回時需要std::move? 並且爲了完成這個問題:在退出函數時需要什麼樣的情況下使用std::move?我認爲以務實的方式獲取這些信息可能會有所幫助。

+1

能否請您展開所有的宏?如果我們看不到它,就不可能知道代碼的作用。 –

+0

@KerrekSB我更新了問題,謝謝。 –

+1

謝謝。這看起來沒有必要,但它可能是解決編譯器錯誤或限制的解決方法。 –

回答

3

你的問題的簡短答案是C++ 11標準所說的。需要執行for_each才能返回一個可移動構造的函數對象/指針。

從標準:

25.2.4對於每個[alg.foreach]

模板功能的for_each(InputIterator的第一,最後InputIterator的, 函數F);

1要求:功能應滿足MoveConstructible (表20)的要求。 [注意:函數不需要符合 CopyConstructible(表21)的要求。 - 注完]

2] E FF學分:將f到範圍[解引用每一迭代中 第一個,最後的結果),從第一開始和前進到持續 - 1. [注意:如果第一SATIS音響ES的類型可變迭代器f的要求可以通過取消引用 迭代器應用非常數函數。結束註釋]

3返回:std :: move(f)。

4複雜性:恰好應用f - 第一次。

5備註:若f返回一個結果,結果被忽略。

項目#3要求std::for_each返回std::move(fn)

而我的問題是爲什麼在返回 這種情況下需要std :: move:

標準要求它的原因是爲了保證返回值是一個可移動構造的函數對象。

爲了完成這個問題:在什麼情況下需要使用 std :: move時返回一個函數?

如果您需要或希望函數的返回值是可移動的,您可以使用return std::move(...)。這允許您在函數退出時訪問返回值的狀態(在for_each示例中,函數對象/指針的狀態)。

僅供參考,表20的標準如下:

Table 20 — MoveConstructible requirements [moveconstructible] 
Expression   Post-condition 
T u = rv;   u is equivalent to the value of rv before the construction 
T(rv)    T(rv) is equivalent to the value of rv before the construction 
[ Note: rv remains a valid object. Its state is unspecified — end note ]