1

Is it legal C++ (this means without undefined behavior, etc.) to set a std::function variable to nullptr from the function/lambda expression stored to this variable when it was invoked?

My intention is to omit further invoking the of std::function.

#include <functional>

std::function<void(int)> func;

void setFunc(std::function<void(int)> f) {
    func = f;
}

int main() {
    setFunc([](int status) {
        // do something...
        setFunc(nullptr); // callback shall only be called once
    });

    for(;;) {
        int status = 0;

        // fetch status

        if (func)
            func(status);
    }
}
Hue James
  • 11
  • 2
  • 2
    [`std::call_once`](https://en.cppreference.com/w/cpp/thread/call_once) is a self-explanatory alternative. – Jarod42 Nov 15 '18 at 10:56
  • The biggest problem isn't that you change the `std::function` but the destruction of the lamda which you're currently in. You can't use any captured variables afterwards. – tkausl Nov 15 '18 at 11:05
  • This is an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – The Quantum Physicist Nov 15 '18 at 11:25
  • I've totally missed `std::call_once`, thank you for the hint. – Hue James Nov 15 '18 at 11:35
  • I vote to reopen: the question is not only about setting the function from the callback, but also about setting it to nullptr with a possible deletion. – Adrian Maire May 20 '21 at 12:11

2 Answers2

0

Your question is an interesting twist on another one, namely:

Is delete this allowed?

The important part is carefully avoiding any use of the lambda's state afterwards.
Your lambda is stateless? That makes it simple.

But anyway, are you sure there's no cleaner alternative for your actual design? std::call_once() for example would be more obvious in this over-simplified example.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
0

You can also set std::function<void(int)> object to a default-constructed one using an empty initializer list:

setFunc({});

To avoid assigning to the function object while it is being called, you may like to make a copy of it and invoke the copy.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271