为什么在此函数中返回时使用了std :: move

时间:2014-01-08 19:33:02

标签: c++ c++11 stl

我刚刚阅读了stl的visual studio实现的algorithm.h头文件,我发现了以下代码:

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 :(得分:3)

您的问题的简短回答是C ++ 11标准这样说。需要for_each的实现来返回一个可移动构造的函数对象/指针。

来自标准:

  

25.2.4对于每个[alg.foreach]

     

模板函数for_each(InputIterator first,InputIterator last,   功能f);

     

1要求:功能应满足MoveConstructible的要求   (表20)。 [注意:功能不需要满足要求   CopyConstructible(表21)。 - 结束说明]

     

2 E ff ects:将f应用于解除引用中每个迭代器的结果   范围[第一个,最后一个],从第一个开始到最后一个 -   1. [注意:如果第一类满足可变迭代器的要求,f可以通过解除引用来应用非常数函数   iterator.- end note]

     

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 ]