passing a lambda with moved capture to function
Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
I recently struggled with a bug hard to find for me.
I tried to pass a lambda to a function taking a std::function
object. The lambda was capturing an noncopyable object.
I figured out, obviously there must happen some copy in between all the passings. I came to this result cause I always ended in an error: use of deleted function
error.
Here the code which produces this error:
void call_func(std::function<void()> func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
return 0;
I solved this by capseling the std::fstream
object in an std::shared_ptr
object. This is working fine, but I think there may be a more sexy way to do this.
I have two questions now:
- Why is this error raising up?
- My Idea: I generate many fstream objects and lambdas in a for loop, for each fstream there is one lambda writing to it. So the access to the fstream objects is only done by the lambdas. I want do this for some callback logic. Is there a more pretty way to this with lambdas like I tried?
c++ lambda c++14
add a comment |Â
up vote
6
down vote
favorite
I recently struggled with a bug hard to find for me.
I tried to pass a lambda to a function taking a std::function
object. The lambda was capturing an noncopyable object.
I figured out, obviously there must happen some copy in between all the passings. I came to this result cause I always ended in an error: use of deleted function
error.
Here the code which produces this error:
void call_func(std::function<void()> func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
return 0;
I solved this by capseling the std::fstream
object in an std::shared_ptr
object. This is working fine, but I think there may be a more sexy way to do this.
I have two questions now:
- Why is this error raising up?
- My Idea: I generate many fstream objects and lambdas in a for loop, for each fstream there is one lambda writing to it. So the access to the fstream objects is only done by the lambdas. I want do this for some callback logic. Is there a more pretty way to this with lambdas like I tried?
c++ lambda c++14
6
/OT: Don't useconst_cast
, instead mark your lambda asmutable
.
â Rakete1111
4 hours ago
BTW, yourconst_cast
is UB. You can't modify objects that were casted this way. The correct way to do this, as Rakete1111 pointed out, is to mark the objectmutable
â Cássio Renan
4 hours ago
Why I have to make it mutable?
â JulianH
4 hours ago
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I recently struggled with a bug hard to find for me.
I tried to pass a lambda to a function taking a std::function
object. The lambda was capturing an noncopyable object.
I figured out, obviously there must happen some copy in between all the passings. I came to this result cause I always ended in an error: use of deleted function
error.
Here the code which produces this error:
void call_func(std::function<void()> func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
return 0;
I solved this by capseling the std::fstream
object in an std::shared_ptr
object. This is working fine, but I think there may be a more sexy way to do this.
I have two questions now:
- Why is this error raising up?
- My Idea: I generate many fstream objects and lambdas in a for loop, for each fstream there is one lambda writing to it. So the access to the fstream objects is only done by the lambdas. I want do this for some callback logic. Is there a more pretty way to this with lambdas like I tried?
c++ lambda c++14
I recently struggled with a bug hard to find for me.
I tried to pass a lambda to a function taking a std::function
object. The lambda was capturing an noncopyable object.
I figured out, obviously there must happen some copy in between all the passings. I came to this result cause I always ended in an error: use of deleted function
error.
Here the code which produces this error:
void call_func(std::function<void()> func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
return 0;
I solved this by capseling the std::fstream
object in an std::shared_ptr
object. This is working fine, but I think there may be a more sexy way to do this.
I have two questions now:
- Why is this error raising up?
- My Idea: I generate many fstream objects and lambdas in a for loop, for each fstream there is one lambda writing to it. So the access to the fstream objects is only done by the lambdas. I want do this for some callback logic. Is there a more pretty way to this with lambdas like I tried?
c++ lambda c++14
c++ lambda c++14
edited 3 hours ago
Cássio Renan
3,0891340
3,0891340
asked 4 hours ago
JulianH
1688
1688
6
/OT: Don't useconst_cast
, instead mark your lambda asmutable
.
â Rakete1111
4 hours ago
BTW, yourconst_cast
is UB. You can't modify objects that were casted this way. The correct way to do this, as Rakete1111 pointed out, is to mark the objectmutable
â Cássio Renan
4 hours ago
Why I have to make it mutable?
â JulianH
4 hours ago
add a comment |Â
6
/OT: Don't useconst_cast
, instead mark your lambda asmutable
.
â Rakete1111
4 hours ago
BTW, yourconst_cast
is UB. You can't modify objects that were casted this way. The correct way to do this, as Rakete1111 pointed out, is to mark the objectmutable
â Cássio Renan
4 hours ago
Why I have to make it mutable?
â JulianH
4 hours ago
6
6
/OT: Don't use
const_cast
, instead mark your lambda as mutable
.â Rakete1111
4 hours ago
/OT: Don't use
const_cast
, instead mark your lambda as mutable
.â Rakete1111
4 hours ago
BTW, your
const_cast
is UB. You can't modify objects that were casted this way. The correct way to do this, as Rakete1111 pointed out, is to mark the object mutable
â Cássio Renan
4 hours ago
BTW, your
const_cast
is UB. You can't modify objects that were casted this way. The correct way to do this, as Rakete1111 pointed out, is to mark the object mutable
â Cássio Renan
4 hours ago
Why I have to make it mutable?
â JulianH
4 hours ago
Why I have to make it mutable?
â JulianH
4 hours ago
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
7
down vote
accepted
The error happens because your lambda has non-copyable captures, making the lambda itself not copyable. std::function
requires that the wrapped object be copy-constructible.
If you have control over call_func
, make it a template:
template<typename T>
void call_func(T&& func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
But this still has undefined behavior in that const_cast
. The easiest way to solve it is to capture by reference instead:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [&fs] fs.close(); ;
call_func(lam);
Or, if you really want to move the object, mark the lambda as mutable
:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] () mutable fs.close(); ;
call_func(lam);
Just keep in mind mutable lamdas aren't really good design.
Following is my take on your idea in (2). Since std::function
requires the wrapped object to be copy-constructible, we can make our own function wrapper that does not have this restriction:
#include <algorithm>
#include <fstream>
#include <iterator>
#include <utility>
#include <memory>
#include <sstream>
#include <vector>
template<typename T>
void call_func(T&& func)
func();
// All functors have a common base, so we will be able to store them in a single container.
struct baseFunctor
virtual void operator()()=0;
;
// The actual functor is as simple as it gets.
template<typename T>
class functor : public baseFunctor
T f;
public:
template<typename U>
functor(U&& f)
: f(std::forward<U>(f))
void operator()() override
f();
;
// In C++17 you don't need this: functor's default constructor can already infer T.
template<typename T>
auto makeNewFunctor(T&& v)
return std::unique_ptr<baseFunctor>(new functor<T>std::forward<T>(v));
int main()
// We need to store pointers instead of values, for the virtual function mechanism to behave correctly.
std::vector<std::unique_ptr<baseFunctor>> functors;
// Generate 10 functors writing to 10 different file streams
std::generate_n(std::back_inserter(functors), 10, ()
static int i=0;
std::ostringstream oss"test";
oss << ++i << ".txt";
std::fstream fsoss.str(), std::fstream::out;
return makeNewFunctor([fs = std::move(fs)] () mutable fs.close(); );
);
// Execute the functors
for (auto& functor : functors)
call_func(*functor);
Note that the overhead from the virtual call is unavoidable: Since you need functors with different behavior stored in the same container, you essentially need polymorphic behavior one way or the other. So you either implement this polymorphism by hand, or use virtual
. I prefer the latter.
There's nothing wrong with amutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.
â François Andrieux
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.
â Cássio Renan
4 hours ago
1
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it withstd::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)
â Cássio Renan
3 hours ago
 |Â
show 6 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
The error happens because your lambda has non-copyable captures, making the lambda itself not copyable. std::function
requires that the wrapped object be copy-constructible.
If you have control over call_func
, make it a template:
template<typename T>
void call_func(T&& func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
But this still has undefined behavior in that const_cast
. The easiest way to solve it is to capture by reference instead:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [&fs] fs.close(); ;
call_func(lam);
Or, if you really want to move the object, mark the lambda as mutable
:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] () mutable fs.close(); ;
call_func(lam);
Just keep in mind mutable lamdas aren't really good design.
Following is my take on your idea in (2). Since std::function
requires the wrapped object to be copy-constructible, we can make our own function wrapper that does not have this restriction:
#include <algorithm>
#include <fstream>
#include <iterator>
#include <utility>
#include <memory>
#include <sstream>
#include <vector>
template<typename T>
void call_func(T&& func)
func();
// All functors have a common base, so we will be able to store them in a single container.
struct baseFunctor
virtual void operator()()=0;
;
// The actual functor is as simple as it gets.
template<typename T>
class functor : public baseFunctor
T f;
public:
template<typename U>
functor(U&& f)
: f(std::forward<U>(f))
void operator()() override
f();
;
// In C++17 you don't need this: functor's default constructor can already infer T.
template<typename T>
auto makeNewFunctor(T&& v)
return std::unique_ptr<baseFunctor>(new functor<T>std::forward<T>(v));
int main()
// We need to store pointers instead of values, for the virtual function mechanism to behave correctly.
std::vector<std::unique_ptr<baseFunctor>> functors;
// Generate 10 functors writing to 10 different file streams
std::generate_n(std::back_inserter(functors), 10, ()
static int i=0;
std::ostringstream oss"test";
oss << ++i << ".txt";
std::fstream fsoss.str(), std::fstream::out;
return makeNewFunctor([fs = std::move(fs)] () mutable fs.close(); );
);
// Execute the functors
for (auto& functor : functors)
call_func(*functor);
Note that the overhead from the virtual call is unavoidable: Since you need functors with different behavior stored in the same container, you essentially need polymorphic behavior one way or the other. So you either implement this polymorphism by hand, or use virtual
. I prefer the latter.
There's nothing wrong with amutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.
â François Andrieux
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.
â Cássio Renan
4 hours ago
1
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it withstd::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)
â Cássio Renan
3 hours ago
 |Â
show 6 more comments
up vote
7
down vote
accepted
The error happens because your lambda has non-copyable captures, making the lambda itself not copyable. std::function
requires that the wrapped object be copy-constructible.
If you have control over call_func
, make it a template:
template<typename T>
void call_func(T&& func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
But this still has undefined behavior in that const_cast
. The easiest way to solve it is to capture by reference instead:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [&fs] fs.close(); ;
call_func(lam);
Or, if you really want to move the object, mark the lambda as mutable
:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] () mutable fs.close(); ;
call_func(lam);
Just keep in mind mutable lamdas aren't really good design.
Following is my take on your idea in (2). Since std::function
requires the wrapped object to be copy-constructible, we can make our own function wrapper that does not have this restriction:
#include <algorithm>
#include <fstream>
#include <iterator>
#include <utility>
#include <memory>
#include <sstream>
#include <vector>
template<typename T>
void call_func(T&& func)
func();
// All functors have a common base, so we will be able to store them in a single container.
struct baseFunctor
virtual void operator()()=0;
;
// The actual functor is as simple as it gets.
template<typename T>
class functor : public baseFunctor
T f;
public:
template<typename U>
functor(U&& f)
: f(std::forward<U>(f))
void operator()() override
f();
;
// In C++17 you don't need this: functor's default constructor can already infer T.
template<typename T>
auto makeNewFunctor(T&& v)
return std::unique_ptr<baseFunctor>(new functor<T>std::forward<T>(v));
int main()
// We need to store pointers instead of values, for the virtual function mechanism to behave correctly.
std::vector<std::unique_ptr<baseFunctor>> functors;
// Generate 10 functors writing to 10 different file streams
std::generate_n(std::back_inserter(functors), 10, ()
static int i=0;
std::ostringstream oss"test";
oss << ++i << ".txt";
std::fstream fsoss.str(), std::fstream::out;
return makeNewFunctor([fs = std::move(fs)] () mutable fs.close(); );
);
// Execute the functors
for (auto& functor : functors)
call_func(*functor);
Note that the overhead from the virtual call is unavoidable: Since you need functors with different behavior stored in the same container, you essentially need polymorphic behavior one way or the other. So you either implement this polymorphism by hand, or use virtual
. I prefer the latter.
There's nothing wrong with amutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.
â François Andrieux
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.
â Cássio Renan
4 hours ago
1
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it withstd::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)
â Cássio Renan
3 hours ago
 |Â
show 6 more comments
up vote
7
down vote
accepted
up vote
7
down vote
accepted
The error happens because your lambda has non-copyable captures, making the lambda itself not copyable. std::function
requires that the wrapped object be copy-constructible.
If you have control over call_func
, make it a template:
template<typename T>
void call_func(T&& func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
But this still has undefined behavior in that const_cast
. The easiest way to solve it is to capture by reference instead:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [&fs] fs.close(); ;
call_func(lam);
Or, if you really want to move the object, mark the lambda as mutable
:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] () mutable fs.close(); ;
call_func(lam);
Just keep in mind mutable lamdas aren't really good design.
Following is my take on your idea in (2). Since std::function
requires the wrapped object to be copy-constructible, we can make our own function wrapper that does not have this restriction:
#include <algorithm>
#include <fstream>
#include <iterator>
#include <utility>
#include <memory>
#include <sstream>
#include <vector>
template<typename T>
void call_func(T&& func)
func();
// All functors have a common base, so we will be able to store them in a single container.
struct baseFunctor
virtual void operator()()=0;
;
// The actual functor is as simple as it gets.
template<typename T>
class functor : public baseFunctor
T f;
public:
template<typename U>
functor(U&& f)
: f(std::forward<U>(f))
void operator()() override
f();
;
// In C++17 you don't need this: functor's default constructor can already infer T.
template<typename T>
auto makeNewFunctor(T&& v)
return std::unique_ptr<baseFunctor>(new functor<T>std::forward<T>(v));
int main()
// We need to store pointers instead of values, for the virtual function mechanism to behave correctly.
std::vector<std::unique_ptr<baseFunctor>> functors;
// Generate 10 functors writing to 10 different file streams
std::generate_n(std::back_inserter(functors), 10, ()
static int i=0;
std::ostringstream oss"test";
oss << ++i << ".txt";
std::fstream fsoss.str(), std::fstream::out;
return makeNewFunctor([fs = std::move(fs)] () mutable fs.close(); );
);
// Execute the functors
for (auto& functor : functors)
call_func(*functor);
Note that the overhead from the virtual call is unavoidable: Since you need functors with different behavior stored in the same container, you essentially need polymorphic behavior one way or the other. So you either implement this polymorphism by hand, or use virtual
. I prefer the latter.
The error happens because your lambda has non-copyable captures, making the lambda itself not copyable. std::function
requires that the wrapped object be copy-constructible.
If you have control over call_func
, make it a template:
template<typename T>
void call_func(T&& func)
func();
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] const_cast<std::fstream&>(fs).close(); ;
call_func(lam);
But this still has undefined behavior in that const_cast
. The easiest way to solve it is to capture by reference instead:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [&fs] fs.close(); ;
call_func(lam);
Or, if you really want to move the object, mark the lambda as mutable
:
int main()
std::fstream fs"test.txt", std::fstream::out;
auto lam = [fs = std::move(fs)] () mutable fs.close(); ;
call_func(lam);
Just keep in mind mutable lamdas aren't really good design.
Following is my take on your idea in (2). Since std::function
requires the wrapped object to be copy-constructible, we can make our own function wrapper that does not have this restriction:
#include <algorithm>
#include <fstream>
#include <iterator>
#include <utility>
#include <memory>
#include <sstream>
#include <vector>
template<typename T>
void call_func(T&& func)
func();
// All functors have a common base, so we will be able to store them in a single container.
struct baseFunctor
virtual void operator()()=0;
;
// The actual functor is as simple as it gets.
template<typename T>
class functor : public baseFunctor
T f;
public:
template<typename U>
functor(U&& f)
: f(std::forward<U>(f))
void operator()() override
f();
;
// In C++17 you don't need this: functor's default constructor can already infer T.
template<typename T>
auto makeNewFunctor(T&& v)
return std::unique_ptr<baseFunctor>(new functor<T>std::forward<T>(v));
int main()
// We need to store pointers instead of values, for the virtual function mechanism to behave correctly.
std::vector<std::unique_ptr<baseFunctor>> functors;
// Generate 10 functors writing to 10 different file streams
std::generate_n(std::back_inserter(functors), 10, ()
static int i=0;
std::ostringstream oss"test";
oss << ++i << ".txt";
std::fstream fsoss.str(), std::fstream::out;
return makeNewFunctor([fs = std::move(fs)] () mutable fs.close(); );
);
// Execute the functors
for (auto& functor : functors)
call_func(*functor);
Note that the overhead from the virtual call is unavoidable: Since you need functors with different behavior stored in the same container, you essentially need polymorphic behavior one way or the other. So you either implement this polymorphism by hand, or use virtual
. I prefer the latter.
edited 3 hours ago
answered 4 hours ago
Cássio Renan
3,0891340
3,0891340
There's nothing wrong with amutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.
â François Andrieux
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.
â Cássio Renan
4 hours ago
1
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it withstd::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)
â Cássio Renan
3 hours ago
 |Â
show 6 more comments
There's nothing wrong with amutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.
â François Andrieux
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.
â Cássio Renan
4 hours ago
1
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it withstd::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)
â Cássio Renan
3 hours ago
There's nothing wrong with a
mutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.â François Andrieux
4 hours ago
There's nothing wrong with a
mutable
lambda if it's known that it will run just once. For example, there's no risk in pushing a mutable lambda to a work queue.â François Andrieux
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
First, thanks a lot, but auto lam = [fs = std::move(fs)] () mutable fs.close(); ; call_func(lam); does end in the same error for me. and your other solutions doesn't fit cause the std::fstream objects is longly out of scope when the lambdas are getting invoked.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
I want bind the std::fstream somehow to the lambda.
â JulianH
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,
call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.â Cássio Renan
4 hours ago
@FrançoisAndrieux agreed. Still, it's better to not use them if there are other options available. Changes to code that uses mutable lambdas may cause unexpected behavior and hard to find bugs. For instance,
call_func
may in the future be changed to call the passed argument more than once under certain conditions: Note that the maintainer of that function may have no idea the argument being passed can not be called more than once.â Cássio Renan
4 hours ago
1
1
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it with
std::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)â Cássio Renan
3 hours ago
@JulianH I'm sorry, I didn't understand your question. You can move a copyable object into the lambda and you will be able to use it with
std::function
normally. e.g: just because you're moving the object, this does not mean the object must be not copyable. I edited my answer with my take on your idea in (2)â Cássio Renan
3 hours ago
 |Â
show 6 more comments
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52345009%2fpassing-a-lambda-with-moved-capture-to-function%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
6
/OT: Don't use
const_cast
, instead mark your lambda asmutable
.â Rakete1111
4 hours ago
BTW, your
const_cast
is UB. You can't modify objects that were casted this way. The correct way to do this, as Rakete1111 pointed out, is to mark the objectmutable
â Cássio Renan
4 hours ago
Why I have to make it mutable?
â JulianH
4 hours ago