passing a lambda with moved capture to function

The name of the pictureThe name of the pictureThe name of the pictureClash 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:



  1. Why is this error raising up?

  2. 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?









share|improve this question



















  • 6




    /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











  • Why I have to make it mutable?
    – JulianH
    4 hours ago















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:



  1. Why is this error raising up?

  2. 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?









share|improve this question



















  • 6




    /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











  • Why I have to make it mutable?
    – JulianH
    4 hours ago













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:



  1. Why is this error raising up?

  2. 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?









share|improve this question















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:



  1. Why is this error raising up?

  2. 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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Cássio Renan

3,0891340




3,0891340










asked 4 hours ago









JulianH

1688




1688







  • 6




    /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











  • Why I have to make it mutable?
    – JulianH
    4 hours ago













  • 6




    /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











  • 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













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.






share|improve this answer






















  • 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











  • 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 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











Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















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






























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.






share|improve this answer






















  • 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











  • 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 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















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.






share|improve this answer






















  • 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











  • 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 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













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.






share|improve this answer














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.







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 hours ago

























answered 4 hours ago









Cássio Renan

3,0891340




3,0891340











  • 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











  • 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 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

















  • 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











  • 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 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
















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


















 

draft saved


draft discarded















































 


draft saved


draft discarded














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













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

Installing NextGIS Connect into QGIS 3?

One-line joke