Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does std::function reset its internal function after being moved

Tags:

c++

c++11

#include <iostream>
using namespace std;

#include <functional>

        template <class F>
        class ScopeExitFunction
        {
        public:
            ScopeExitFunction(F& func) throw() :
                m_func(func)
            {
            }

            ScopeExitFunction(F&& func) throw() :
                m_func(std::move<F>(func))
            {
            }

            ScopeExitFunction(ScopeExitFunction&& other) throw() :
                m_func(std::move(other.m_func))
            {
             //  other.m_func = []{};
            }

            ~ScopeExitFunction() throw()
            {
                m_func();
            }

        private:
            F m_func;
        };

int main() {
    {
        std::function<void()> lambda = [] { cout << "called" << endl; };
        ScopeExitFunction<decltype(lambda)> f(lambda);
        ScopeExitFunction<decltype(lambda)> f2(std::move(f));
    }
    return 0;
}

without uncomment this line // other.m_func = []{}; the program produce this output :

Executing the program.... $demo called terminate called after throwing an instance of 'std::bad_function_call' what(): bad_function_call

is it normal that std::function doesn't reset his internal function when moved ?

like image 420
Guillaume Paris Avatar asked Nov 15 '13 10:11

Guillaume Paris


2 Answers

According to C++11 20.8.11.2.1/6 [func.wrap.func.con], move-constructing from an existing std::function object leaves the original object "in a valid state with an unspecified value". So basically don't assume anything. Just don't use the original function object, or don't move from it if you still need it.

like image 88
Kerrek SB Avatar answered Nov 15 '22 05:11

Kerrek SB


is it normal that std::function doesn't reset his internal function when moved ?

On the contrary, in your case it does reset the internal function, meaning the internal handle is set to zero, and the std::function is not a real function any more. And since that happened the call to operator() does not go well.

like image 40
Arne Mertz Avatar answered Nov 15 '22 05:11

Arne Mertz