本文介绍了我应该通过const-reference传递一个std ::函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 假设我有一个函数,它接受 std :: function : void callFunction(std :: function< void()> x) {x } 我应该通过 x by const-reference instead?: void callFunction(const std :: function< void()>& x) {x(); } 这个问题的答案是否根据函数的作用而改变?例如,如果它是一个类成员函数或构造函数,它将 std :: function 存储或初始化成一个成员变量。 假设你有一个叫做run的函数,如果你想要性能,这在UI线程。 std :: future< void>运行在ui中的一些代码的run_in_ui_thread(std :: function< void()>) future 的信号。 (在UI框架中UI线程是你应该混淆UI元素的地方)。 我们有两个签名: std :: future< void> run_in_ui_thread(std :: function< void()>)//(A) std :: future< void> run_in_ui_thread(std :: function< void()> const&)//(B) ,我们可能使用这些如下: run_in_ui_thread([=] { //代码在这里}).wait(); 这将创建一个匿名闭包(一个lambda),构造一个 std: :function ,将它传递给 run_in_ui_thread 函数,然后等待它在主线程中运行。 在情况(A)中, std :: function 直接从我们的lambda构造,然后在 run_in_ui_thread 。 lambda是 move d到 std :: function ,所以任何可移动状态被有效地携带到它。 p> 在第二种情况下,创建一个临时 std :: function ,lambda是 move d,然后在 run_in_ui_thread std :: function >。 到目前为止,很好 - 他们两个执行相同。除了 run_in_ui_thread 会将其函数参数的副本发送到ui线程执行! (它会在它完成之前返回,所以它不能只使用它的引用)。对于情况(A),我们简单地将 move 将 std :: function 插入其长期存储。在情况(B)中,我们不得不复制 std :: function 。 价值更优。如果有可能你存储一个 std :: function 的副本,传递值。否则,任何一种方式大致相等:唯一的缺点是by-value是如果你采取相同的大块 std :: function ,并有一个子方法在另一个使用它。除非, move 将与 const& 同样有效。 现在,如果我们在 std :: function 中有持久化状态,两者之间还有一些其他的区别。 假设 std :: function 存储了一个带有 operator()const ,但它也有一些可变的数据成员修改它(多么的粗鲁!)。 code> std :: function<> const& 情况下,修改的 mutable 数据成员将传播出函数调用。在 std :: function<> 情况下,他们不会。 这是一个相对奇怪的角 你想要治疗 std :: function ,就像你会有任何其他可能的重量,类型。移动很便宜,复制可能很昂贵。 Let's say I have a function which takes an std::function:void callFunction(std::function<void()> x){ x();}Should I pass x by const-reference instead?:void callFunction(const std::function<void()>& x){ x();}Does the answer to this question change depending on what the function does with it? For example if it is a class member function or constructor which stores or initializes the std::function into a member variable. 解决方案 If you want performance, pass by value if you are storing it.Suppose you have a function called "run this in the UI thread".std::future<void> run_in_ui_thread( std::function<void()> )which runs some code in the "ui" thread, then signals the future when done. (Useful in UI frameworks where the UI thread is where you are supposed to mess with UI elements)We have two signatures we are considering:std::future<void> run_in_ui_thread( std::function<void()> ) // (A)std::future<void> run_in_ui_thread( std::function<void()> const& ) // (B)Now, we are likely to use these as follows:run_in_ui_thread( [=]{ // code goes here} ).wait();which will create an anonymous closure (a lambda), construct a std::function out of it, pass it to the run_in_ui_thread function, then wait for it to finish running in the main thread.In case (A), the std::function is directly constructed from our lambda, which is then used within the run_in_ui_thread. The lambda is moved into the std::function, so any movable state is efficiently carried into it.In the second case, a temporary std::function is created, the lambda is moved into it, then that temporary std::function is used by reference within the run_in_ui_thread.So far, so good -- the two of them perform identically. Except the run_in_ui_thread is going to make a copy of its function argument to send to the ui thread to execute! (it will return before it is done with it, so it cannot just use a reference to it). For case (A), we simply move the std::function into its long-term storage. In case (B), we are forced to copy the std::function.That store makes passing by value more optimal. If there is any possibility you are storing a copy of the std::function, pass by value. Otherwise, either way is roughly equivalent: the only downside to by-value is if you are taking the same bulky std::function and having one sub method after another use it. Barring that, a move will be as efficient as a const&.Now, there are some other differences between the two that mostly kick in if we have persistent state within the std::function.Assume that the std::function stores some object with a operator() const, but it also has some mutable data members which it modifies (how rude!).In the std::function<> const& case, the mutable data members modified will propagate out of the function call. In the std::function<> case, they won't.This is a relatively strange corner case.You want to treat std::function like you would any other possibly heavy-weight, cheaply movable type. Moving is cheap, copying can be expensive. 这篇关于我应该通过const-reference传递一个std ::函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-20 10:53