Reputation: 870
I have been reading Lambda capture as const reference?
It is an interesting feature, and sometimes I also wish this feature to exist, especially when I have huge data, which I need to access inside a lambda function.
My follow up questions -
Let us assume we can.
We assume [const &]
as syntax to capture.
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 ?
My intuition is that is should behave just like [&]
but the captured value should not be allowed to modify.
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 &'!
}
Upvotes: 2
Views: 3826
Reputation: 11317
I've been wondering about this myself.
Since the operator() is const by default, I would assume that allowing const references is acceptable as well.
With the current standards(C++17), the closest I got to this behaviour is:
auto c = [ &x = std::as_const(x) ] () { std::cout << x << std::endl; };
Workaround in C++11/C++14 would be(thanks to Daniel for suggestion):
auto const & crx = x;
auto c = [ &crx ] () { std::cout << crx << std::endl; };
Upvotes: 4
Reputation: 66200
Maybe not exactly what you're looking for but... I suppose you can pass through a function that receive the same value by const reference.
Something as follows
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();
If you try to modify x
inside the lambda
std::cout << x++ << std::endl;
you should get an error.
As you can see, from, this solution you get that x
can't be modified inside the lambda but the lambda is influenced from the value changes outside
int x { 42 };
auto l = make_capture_const(x);
l(); // print 42
x = 43;
l(); // print 43
IMHO, an hypothetic [const &]
capture syntax should works in the same way. But I understand that is highly questionable.
Upvotes: 1
Reputation: 23497
lambda(); // should it print 11 or 10 ?
I don't understand why it should print 10. Consider lambda
being just an instance of some anonymous class. Making it a normal class, it should look like:
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 ?
The meaning of const reference here is only that you cannot modify x
through i_
member reference variable.
A simlpler scenario:
int x = 10;
const int & crx = x;
x++;
std::cout << crx << std::endl; // prints 11
Upvotes: 4