template<typename F>
void call_me(F f)
{
f();
}
现在,调用call_me(ftor{})
可能会调用ftor
的copy构造函数(它很可能是copy省略的,所以情况并非如此)。但ftor f{};call_me(f);
将导致复制。如果ftor
包含大量数据,则可能是一个问题。
我们将通过将其作为常量引用(void call_me(const f&f)
)传递来改进它,以消除不需要的副本。只要ftor::operator()
是const
就可以。如果不是,则调用call_me
将导致编译错误(丢失const
限定符)。
所以,为什么要费心使用常量引用,只使用reference(void call_me(f&f)
)。这很好,但对于第一种情况call_me(ftor{})
就不起作用了,因为将r-value绑定到(非常量)l-value引用是无效的。
声明f
作为转发引用(void call_me(f&&f)
)似乎在所有情况下都有效。我相信,这是由于引用崩溃而起作用的。
那么,为什么模板化的函子不作为STL中函数的转发引用传递呢?
为什么模板化的函子不作为来自STL的函数中的r值引用传递?
首先,它们将转发引用,而不是rvalue引用。
这就是说,就像许多关于一般语言设计的“为什么”问题一样,答案可以简单地是:因为还没有人提出这个改变(参见如何提交一个建议)。我怀疑传递到标准库算法中的大量函数对象要么是lambdas,要么是无状态的,要么是极其廉价的可复制的。此外,如果您有一个如此昂贵的对象,您总是可以将其转换为一个成本低廉的可复制对象,以实现算法的目的:
call_me(std::ref(huge_object));
最后,其中一些算法依赖于将这些函数对象传递给其他帮助器。如果算法简单地假设函数对象是“自由”复制的,这使得它易于编码。如果我们在这里引入rvalues的可能性,这就增加了另一层需要处理的问题--我们是否只是在周围传递引用?使用ref限定的运算符()
的函数对象呢?
以上的一些组合可能解释了为什么,例如,它仍然是:
template <class InputIt, class UnaryPredicate>
InputIt find_if(InputIt, InputIt, UnaryPredicate );
而不是
template <class InputIt, class UnaryPredicate>
InputIt find_if(InputIt, InputIt, UnaryPredicate&& );
问题内容: 简而言之,我有一个带有ArrayList参数的方法。在该方法中,出于仅与该方法返回的内容相关的目的,我修改了ArrayList的内容。因此,我根本不希望作为参数传递的ArrayList受到影响(即,不作为引用传递)。 我尝试过的一切都未能达到预期的效果。我需要怎么做才能只使用方法内ArrayList的副本,而不能更改实际变量? 问题答案: 即使您有办法将数组列表作为副本而不是通过引用传
我正在学习结构化绑定声明。我的理解是,
让我们考虑以下代码: 我知道第二个声明是重载,而不是部分专业化: 但我想知道它与部分专业化有何不同?它为我们提供了与部分专业化相同的功能,不是吗?
我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误
我的讲师在课堂上问过我这个问题,我想知道为什么是宏而不是函数?
问题内容: Java的WeakHashMap通常被认为对缓存有用。尽管其弱引用是根据地图的键而不是其值定义的,但这似乎很奇怪。我的意思是,这是我要缓存的值,而一旦缓存中没有其他人强烈引用它们,我想收集垃圾值,不是吗? 以哪种方式保留对键的弱引用?如果执行a ,那么我希望高速缓存保持在’o’状态,直到调用者不再拥有强引用,并且我完全不在乎字符串对象“ some_key”。 我想念什么吗? 问题答案: