2015-12-22 40 views
6

有时候我会在包含参数的5个本地变量的本地函数中执行std::find_if(例如)。但是,传入STL算法的lambda只需要访问其中的一个。什么时候更喜欢显式捕获lambda而不是隐式捕获?

void foo(int one, int two, int three) 
{ 
    std::vector<int> m_numbers; 
    int four, five; 

    std::find_if(m_numbers.begin(), m_numbers.end(), [=](int number) { 
     return number == four; 
    }); 
} 

或者,我可以做的:我可以在以下两种方式之一捕获此

void foo(int one, int two, int three) 
{ 
    std::vector<int> m_numbers; 
    int four, five; 

    std::find_if(m_numbers.begin(), m_numbers.end(), [four](int number) { 
     return number == four; 
    }); 
} 

(注意:我没有编译这段代码,歉意任何语法错误或其他错误)

我知道隐式捕获是基于odr-used规则,所以在功能和实现方面,我认为两者是相同的。你什么时候使用显式捕获而不是隐式捕获?我唯一的想法与封装的原理有些相关:只访问你需要的东西允许编译器帮助你确定何时访问你不应该访问的变量。它还保持方法的本地状态(它是不变的,在执行过程中函数的生命周期)更安全。但这些真的是实际问题吗?

是否有功能原因使用显式捕获而不是隐式捕获?遵循什么是一个好的经验法则或最佳实践?

+2

IIRC,斯科特迈尔斯建议(在他的最新著作),以几乎只使用隐式捕捉这样的情况下,它的参数传递给函数使用它并不保留它。当然,在各种情况下使用隐式捕获时,陷阱可能会陷入其中。 – chris

+0

这种陷阱的例子将不胜感激。这些例子将有助于对比差异并帮助建立良好的一般实践规则。 –

+6

@chris斯科特迈耶斯的推荐是另一种方式。有效的现代C++,第31项:避免默认捕获模式。 – LogicStuff

回答

2
  • 明确捕获始终是最好,因为它是不容易出错
  • 这是更好的重物(不是简单的整型,双等)的情况下,使用&
  • 使用,当你打算使用=你的lambda超出了变量捕获的范围。随着&是有风险得到晃来晃去参照当地销毁变量
2

在运行时使用[=][&]时没有命名任何名称是最简单和最高效的。

在这些情况下,如this answer所述,仅当变量为odr-used时才会捕获变量。换句话说,编译器只捕获需要的东西。

如果指定捕获列表,然后两个不同之处可能发生:

  • 您忘记捕捉拉姆达使用
  • 您捕捉的东西,拉姆达并不需要的东西。

在第二种情况下,如果按值捕获,这意味着该对象被不必要地复制。

所以,我的建议是使用[],[&][=],除非你能想到一个很好的理由,否则对于一个特定的情况。一个这样的情况可能是,如果你想通过引用捕获一些变量,并按价值捕获一些变量。

相关问题