Say I have some sort of type wrapping up a function, maybe a lambda function:
template<typename Function>
struct my_struct
{
Function f;
my_struct(const Function &f) : f(f) {}
};
What happens when an instance of this type is assigned? My understanding is that lambdas are immutable, and have deleted assignment operators.
Yet, when I assign to an object this type in the code snippet below, no error is emitted:
// a structure which contains a function;
// possibly a lambda function
template<typename Function>
struct my_struct
{
Function f;
my_struct(const Function &f) : f(f) {}
// XXX adding this assignment operator causes an error
//my_struct &operator=(const my_struct &other)
//{
// f = other.f;
// return *this;
//}
};
template<typename Function>
my_struct<Function> make_struct(const Function &f)
{
return my_struct<Function>(f);
}
int main()
{
// create some lambda
auto lambda = [](int x){return x;};
// make a struct containing a copy of the lambda
auto x = make_struct(lambda);
// try to assign to the struct, which
// presumably assigns to the enclosed lambda
x = make_struct(lambda);
return 0;
}
Adding the commented-out assignment operator yields an error, as expected:
$ g++-4.6 -std=c++0x test.cpp
test.cpp: In member function ‘my_struct<Function>& my_struct<Function>::operator=(const my_struct<Function>&) [with Function = main()::<lambda(int)>, my_struct<Function> = my_struct<main()::<lambda(int)> >]’:
test.cpp:34:25: instantiated from here
test.cpp:13:5: error: use of deleted function ‘main()::<lambda(int)>& main()::<lambda(int)>::operator=(const main()::<lambda(int)>&)’
test.cpp:27:18: error: a lambda closure type has a deleted copy assignment operator
So, is it possible to create assignable types with lambda member variables? This seems like a reasonable thing to want to try. Consider combining a lambda with boost::transform_iterator
, for example.
You're close. A lambda has an implicit copy-constructor and may have — depending on the captured values — an implicit move-constructor. It has a deleted copy-assignment operator.
In other words, you may construct it, but you may not assign it. If you're looking for a generic function object, you want to use std::function<>
. It emulates functions as first-class values.
Note that immutable is different from assignable. When a lambda is called mutable, that means its function-call body can modify the members of the lambda (i.e., the function is not const
):
int i = 0;
auto okay = [=](int x) mutable { i += x; };
auto error = [=](int x) { i += x; };
Each of these is copy-constructable and non-assignable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With