我刚刚读了std :: for_each的代码:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
Run Code Online (Sandbox Code Playgroud)
并且无法看到此模板函数返回输入函数的任何充分理由.有没有人有任何关于这将有用的例子?
C++ 11模式下的GCC 4.7让我定义了一个以两种不同方式获取lambda的函数:
// by value
template<class FunctorT>
void foo(FunctorT f) { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)
和:
// by r-value reference
template<class FunctorT>
void foo(FunctorT&& f) { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)
但不是:
// by reference
template<class FunctorT>
void foo(FunctorT& f) { /* stuff */ }
Run Code Online (Sandbox Code Playgroud)
我知道我可以取消模板化函数,只需要使用std :: functions,但是foo它很小并且内联,我想给编译器提供最好的机会来内联调用它.在前两个中,如果我特别知道我正在传递lambdas,那么这对性能来说是优选的,为什么不允许将lambda传递给最后一个?
在讨论中,我在这里玩弄着传球手.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函数中的转发引用传递?
所以我在这里问了一个问题:Lambda在最新的Visual Studio上运行,但是不起作用在我得到响应的其他地方,我的代码是实现定义的,因为标准的25.1 [algorithms.general] 10说:
除非另有说明,否则允许将函数对象作为参数的算法自由复制这些函数对象.对象标识很重要的程序员应该考虑使用指向非复制实现对象的包装类,例如
reference_wrapper<T>
我想知道为什么会这样?我们被告知我们整个生命中通过引用来获取对象,为什么标准是按值获取函数对象,更糟糕的是我的链接问题制作了这些对象的副本?这样做有什么我不明白的优点吗?
我正在编写标准c ++库的实现用于研究.
C++ 11标准表示for_each返回std::move(f).
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
Returns: std::move(f).
Run Code Online (Sandbox Code Playgroud)
我认为函数范围局部变量在返回时是移动构造的.我应该move(f)明确回来吗?