Zer*_*ges 9 c++ templates c++11
在讨论中,我在这里玩弄着传球手.C++ STL传递函子作为值(见于std::for_each,std::find_if,std::transform)
所以宣布我的就是这样的.
template<typename F>
void call_me(F f)
{
f();
}
Run Code Online (Sandbox Code Playgroud)
现在,调用call_me(ftor{})可能会调用ftor复制构造函数(它很可能是复制省略,所以不是这样).但ftor f{}; call_me(f);会导致复制.如果ftor有大量数据,则可能是个问题.
我们通过将它作为const引用(void call_me(const F& f))传递来去除不需要的副本来改进它.只要ftor::operator()是这样就可以了const.如果不是,则调用call_me将导致编译错误(丢失const限定符).
那么,为什么要使用const引用,只需使用reference(void call_me(F& f)).这很好,但它不适用于第一种情况,call_me(ftor{})因为将r值转换为(非常量)l值引用无效.
声明f为转发引用(void call_me(F&& f))似乎适用于所有情况.我相信,这可以归功于参考折叠.
那么,为什么模板化仿函数不作为STL函数中的转发引用传递?
Bar*_*rry 11
为什么模板化仿函数不作为STL函数中的r值引用传递?
首先,它们是转发引用,而不是右值引用.
也就是说,与许多关于语言设计的"为什么"问题一样,答案可能只是:因为没有人提出过这种改变(请参阅如何提交提案).我怀疑传递到标准库算法的大量函数对象要么是lambdas,要么是无状态的,要么是非常便宜的可复制的.此外,如果您有这样一个昂贵的对象,您可以随时将其转换为便宜的可复制对象,以用于算法:
call_me(std::ref(huge_object));
Run Code Online (Sandbox Code Playgroud)
最后,这些算法中的一些依赖于将这些函数对象传递给其他帮助器.如果算法只是假设函数对象是"免费"进行复制,则可以很容易地进行编码.如果我们在这里介绍rvalues的可能性,这会增加另一层需要处理的问题 - 我们只是传递参考值吗?那些具有ref-qualified的函数对象operator()呢?
上述的某些组合可能解释了为什么,例如,它仍然是:
template <class InputIt, class UnaryPredicate>
InputIt find_if(InputIt, InputIt, UnaryPredicate );
Run Code Online (Sandbox Code Playgroud)
并不是
template <class InputIt, class UnaryPredicate>
InputIt find_if(InputIt, InputIt, UnaryPredicate&& );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
519 次 |
| 最近记录: |