When using C++14's init capture, 'auto' type deduction rules are applied (which throws away the reference, const and volatile)
Notice here that I'm not saying const reference. If I wanted a const reference I can write:
auto lambda = [&widget = std::as_const(widget)] () {};
// C++17
Or I can add & to lhs cast the rhs as a const reference.
what I'm asking for is: can I write something like this?:
auto lambda = [const widget = widget] () {};
There is no way to capture an object by value and have it be const
. The grammar for an init-capture
is
init-capture:
identifier initializer
& identifier initializer
where identifier
is
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
Which means you can only specify a name, without any cv-qualifers. For a non mutable lambda this isn't an issue since the function will be const
and you can't modify a capture by value object.
For a mutable lambda you can capture a reference to const like you do with [&widget = std::as_const(widget)]
. If you can't or don't want to have a reference then you need a write a const wrapper like
template <typename T>
class const_wrapper
{
const T obj;
public:
const_wrapper(T obj) : obj(obj) {}
operator const T&() const { return obj; }
};
The above object is copyable, but not assignable (because of the const member) and only allows const access to the underlying type.