我刚刚阅读了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
的情况?我认为以务实的方式获取这些信息会很有用。
答案 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 ]