我一直在阅读Lambda capture as const reference?
这是一个有趣的功能,有时我也希望这个功能存在,特别是当我有大量数据时,我需要在lambda函数中访问它。
我的后续问题 -
让我们假设我们可以
我们假设[const &]
是要捕获的语法。
int x = 10;
auto lambda = [const & x](){ std::cout << x << std::endl; };
lambda(); // prints 10, great, as expected
x = 11;
lambda(); // should it print 11 or 10 ?
我的直觉是应该表现得像[&]
,但不应该允许修改捕获的值。
template<typename Func>
void higher_order_function(int & x, Func f)
{
f(); // should print 11
x = 12;
f(); // should print 12
}
void foo()
{
int x = 10;
auto c = [const & x] () { std::cout << x << std::endl; };
c(); // should print 10
x = 11;
c(); // should print 11
higher_order_function(x, c);
auto d = [const & x] () { x = 13; }; // Compiler ERROR: Tried to assign to const qualified type 'const int &'!
}
答案 0 :(得分:4)
lambda(); // should it print 11 or 10 ?
我不明白为什么要打印10.考虑lambda
只是某个匿名类的实例。使它成为正常的类,它应该看起来像:
class Lambda {
public:
Lambda(const int & i) : i_(i) { }
void operator()() { std::cout << i_ << std::endl; }
private:
const int & i_;
};
int x = 10;
Lambda lambda(x);
lambda(); // prints 10, great, as expected
x = 11;
lambda(); // should it print 11 or 10 ?
此处const引用的含义仅在于您无法通过x
成员引用变量修改i_
。
一个简单的场景:
int x = 10;
const int & crx = x;
x++;
std::cout << crx << std::endl; // prints 11
答案 1 :(得分:2)
我自己一直在想这个。
由于operator()默认是const,我认为允许const引用也是可接受的。
根据现行标准(C ++ 17),我最接近这种行为是:
auto c = [ &x = std::as_const(x) ] () { std::cout << x << std::endl; };
C ++ 11 / C ++ 14中的解决方法(感谢Daniel的建议):
auto const & crx = x;
auto c = [ &crx ] () { std::cout << crx << std::endl; };
答案 2 :(得分:1)
也许不完全是你想要的但是......我想你可以通过const引用传递一个接收相同值的函数。
以下内容
template <typename T>
auto make_capture_const (T const & x)
{ return [&x](){ std::cout << x << std::endl; }; }
// ...
int x { 42 };
auto l = make_capture_const(x);
l();
如果您尝试修改lambda中的x
std::cout << x++ << std::endl;
你应该收到错误。
正如你所看到的,从这个解决方案中你得到的x
不能在lambda中修改,但lambda会受到外部值变化的影响
int x { 42 };
auto l = make_capture_const(x);
l(); // print 42
x = 43;
l(); // print 43
恕我直言,假设[const &]
捕获语法应该以相同的方式工作。但我明白这是非常值得怀疑的。