2014-01-08 108 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 ]